为什么我的 Bash 脚本无法识别别名?

为什么我的 Bash 脚本无法识别别名?

在我的~/.bashrc文件中有两个定义:

  1. commandA,这是较长路径的别名
  2. commandB,这是 Bash 脚本的别名

我想用这两个命令处理同一个文件,所以我编写了以下 Bash 脚本:


#!/bin/bash

for file in "$@"
    do
    commandA $file
    commandB $file
done

即使在注销会话并重新登录后,command not found当我运行此脚本时,Bash 也会提示我这两个命令的错误。

我究竟做错了什么?

答案1

如果你查看 bash 联机帮助页,你会发现:

当 shell 非交互式时,别名不会展开,除非使用 shopt 设置 Expand_aliases shell 选项(请参阅下面的 SHELL BUILTIN COMMANDS 下的 shopt 描述)。

因此

shopt -s expand_aliases

在你的脚本中。

确保在脚本中设置别名文件后获取别名文件。

shopt -s expand_aliases
source ~/.bash_aliases

答案2

首先,正如 ddeimeke 所说,默认情况下,别名不会在非交互式 shell 中扩展。

其次,.bashrc除非您设置环境变量,否则非交互式 shell 不会读取它BASH_ENV

但最重要的是:不要这样做!请?有一天,您将该脚本移动到未设置必要别名的地方,它会再次中断。

相反,在脚本中设置并使用变量作为快捷方式:

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
do
    $CMDA "$file"
    $CMDB "$file"
done

答案3

别名无法导出,因此它们在未定义别名的 shell 脚本中不可用。换句话说,如果您在中定义它们,则~/.bashrc它们不可用your_script.sh(除非您~/.bashrc在脚本中获取源代码,我不建议这样做,但有一些方法可以正确执行此操作)。

但是,函数可以导出,并且可供从定义函数的环境中运行的 shell 脚本使用。这可以通过将其放入 bashrc 中来完成:

foo()
{
    回声“你好世界!”
}
导出-f foo

正如 Bash 手册所说:“对于几乎所有用途,shell 函数都优于别名。”

答案4

您也可以.在脚本之前使用。运行它作为:

. /path/to/your/script.sh

您可以在 bash 脚本中检查此情况,如下所示:

if [[ $- == *i* ]]
then
    echo "running on interactive mode. aliases will work!"
fi

相关内容