bash - 是什么导致我的别名无法在 shell 脚本中扩展

标签 bash scripting

我正在尝试在脚本中设置别名,然后稍后在脚本中执行别名。我已经验证别名包含的文件路径是有效的,并且我还设置了 shell 脚本来扩展别名,但脚本仍然拒绝使用别名。我在这里可能做错了什么?

脚本:

#set location of parallel script and replace ~ with $HOME if necessary
parallellocation="~/newnnm/parallel"
parallellocation="${parallellocation/#\~/$HOME}"
#If the parallellocation variable is set and a parallel command is not currently available, 
#proceed with setting an alias that points to the parallellocation variable
if [ -r "$parallellocation" ] && ! command -v parallel &>/dev/null; then
        shopt -s expand_aliases
        alias parallel="$parallellocation"
        parallel
fi

示例输出:

./processlocations_new2.sh
./processlocations_new2.sh: line 98: parallel: command not found

最佳答案

正如该问题的评论记录所示,bash似乎不尊重 alias_expand 的别名定义或设置if block 或其他复合命令范围内的选项。 Bash Manual解释一下:

The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input before executing any of the commands on that line. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use alias in compound commands.

(强调。)注释并不直接引用 shell 选项,但复合命令中的别名定义不适用于同一复合命令的相同逻辑也意味着它是 expand_aliases 的值。当读取适用的复合命令时,选项生效。

问题是如何使用 shell 函数而不是别名来实现此目的。这是一种方法:

altparallel="$HOME/newnnm/parallel"

parallellocation=
if command -v parallel >/dev/null 2>&1; then
  parallellocation="command parallel"
elif [[ -x "$altparallel" ]]; then
  parallellocation="$altparallel"
fi

# Runs parallel with the given arguments.  Uses the 'parallel' command
# found in the path if there is one, or a local one designated by
# $altparallel if that exists and is executable.  Exit status is that of
# 'parallel', or 1 if no 'parallel' command is available.
parallel() {
  [[ -z "$parallellocation" ]] && return 1

  # expansion of $parallellocation is intentionally unquoted
  $parallellocation "$@"
}

您可以从环境设置脚本中获取 parallel定义的函数可以执行您想要的操作。

第三,如果您想要的只是一个直接运行一个并行版本或另一个版本的脚本,那么您不需要函数或别名。只需弄清楚您要运行哪个,然后运行它,例如:

altparallel="$HOME/newnnm/parallel"

if command -v parallel >/dev/null 2>&1; then
  parallel "$@"
elif [[ -x "$altparallel" ]]; then
  "$altparallel" "$@"
else
  exit 1
fi

关于bash - 是什么导致我的别名无法在 shell 脚本中扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42699172/

相关文章:

bash - 获取定时进程的 PID 以及时间的输出

linux - 如何编写shell脚本查找PID并Kill

linux - Linux BASH 被发现后尝试启动文件

linux - 如何获取长时间运行的 Linux 进程的启动时间?

javascript - 脚本语言中变量的内存分配是如何完成的?

linux - touch 命令在一个目录下创建多个文件(不同名称)

c# - 从 csx 脚本引用 NuGet 包

powershell - 如何用字符串替换文件名中的第一个字符?

linux - 使用脚本生成一堆新用户以生成 newusers 命令所需的输出

linux - 为什么在尝试使用 sed 命令删除字符串时出现此错误?