为什么 bash 别名在脚本中不起作用?

Why bash alias doesn't work in scripts?

我正在使用 Mac 并且我在 .bashrc:

中定义了这个别名
$cat .bashrc | grep la
alias la='ls -la'

然后我尝试在脚本中使用它:

$cat ./mytest.sh  
#!/bin/bash
la

它运行并说找不到 la:

./mytest.sh: line 2: la: command not found

这是为什么? Mac 和 Linux 我都试过了,同样的错误!

在~/.bashrc文件的开头通常可以找到两行:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

此行将中止对无论如何不推荐的脚本的包含。对于可移植性问题,您通常会编写完整的命令或在脚本本身中定义别名。

您的 .bashrc 仅供交互式 shell 使用。 https://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files 说:

Invoked non-interactively

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

but the value of the PATH variable is not used to search for the filename.

As noted above, if a non-interactive shell is invoked with the --login option, Bash attempts to read and execute commands from the login shell startup files.

如您所见,那里没有关于 .bashrc 的内容。您的别名根本不存在于脚本中。


但是即使 .bashrc 被阅读了,还有 another problem:

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt.

所以如果你想让别名在脚本中工作,你必须先做 shopt -s expand_aliases。或者只使用 shell 函数而不是别名:

la() {
    ls -la
}

解决此问题的最简单方法是在脚本中执行两件重要的事情 - 否则它不会起作用,如果您只执行一件事。

#!/bin/bash -i

# Expand aliases defined in the shell ~/.bashrc
shopt -s expand_aliases

在此之后,您在 ~/.bashrc 中定义的别名将在您的 shell 脚本(giga.sh 或 any.sh)以及任何函数或子项中可用shell 在这样的脚本中。

如果你不这样做,你会得到一个错误:

your_cool_alias: command not found