为什么这个 shell 脚本中包含反斜杠?

为什么这个 shell 脚本中包含反斜杠?

在我的脚本副本中conda.sh,我看到以下几行:

if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
    SYSP=$(\dirname "${CONDA_EXE}")
else
    SYSP=$(\dirname "${CONDA_EXE}")
    SYSP=$(\dirname "${SYSP}")
fi

我很好奇为什么 in 前面有一个d反斜杠dirname。我认为没有必要。反斜杠的这种使用也出现在源文件的其他位置。我是否缺少这样做的理由?

答案1

反斜杠将抑制别名扩展,即它执行原始命令并确保别名版本不运行。当系统设置shopt -s expand_aliases(仅限 BASH)或使用source.

./conda.sh          # usually no alias expansion (unless `shopt -s expand_aliases` in BASH)
source ./conda.sh   # alias expansion
. ./conda.sh        # alias expansion

一些系统管理员喜欢在所有内容中添加反斜杠,作为防止别名副作用的预防措施,以防万一无意中在其他地方使用了别名,并且别名如前面所解释的那样被扩展。例如,如果系统已alias dirname='dirname -z'在某处设置了此值,并且条件允许扩展别名,则尝试调用 dirname 的脚本将不幸地调用dirname -z,这不是脚本预期的。

如果确定这样的别名不存在,我们可以删除所有反斜杠,它应该可以正常工作。

或者,可以使用command而不是反斜杠版本来抑制别名。因此,\dirname可以使用来代替command dirname,这可能看起来更具可读性。 (对于像 之类的内置命令cd,应该使用它builtin)。我更喜欢这个,因为它还绕过具有相同名称的函数以及任何别名。

答案2

如果conda.sh是要获取的文件,则反斜杠用于绕过别名。 Bash 通常会禁用脚本执行的别名扩展,但对于可能在交互式 shell 中运行的源文件,情况并非如此。因此,dirname可能会运行名为 的别名dirname,但\dirname会跳过别名扩展并运行名为 的函数或命令dirname。 (不过,不仅仅是反斜杠,任何引用都可以。)

相关内容