我.bashrc
设置了一堆别名供我根据需要使用,然后自动运行其中一个。
事实证明,这导致自动脚本 ssh-ing 进入我的机器时出现一些问题,而不是使用交互式 shell。因此,为了解决这个问题,我将它们放在 if 块中,这样它们就不会被定义或为那些自动化脚本运行......
if [ -n "$TERM" ] && [ "$TERM" != "dumb" ] ; then
alias short='long command here'
alias another='very long command here'
# ...
short
fi
只能看看short: command not found
!
让我们把这个减少到最低限度......
$ cat alias.sh
alias foo='echo hi'
foo
$ sh alias.sh
hi
cat alias-in-if.sh
if true ; then
alias foo='echo hi'
foo
fi
sh alias-in-if.sh
alias-in-if.sh: line 3: foo: command not found
为什么第一个脚本有效,而第二个脚本无效?
(我已经回答了我自己的问题。)
答案1
我四处搜索,没有发现与 ifs 内的别名有关的任何内容,只有函数内的别名,这起初似乎是一个不同的问题。
但实际上,这个答案解决它:
Bash 总是先读取至少一行完整的输入,然后再执行该行上的任何命令。[...] 该行上别名定义后面的命令不受新别名的影响。[...] 为了安全起见,请始终将别名定义放在单独的行上,并且不要在复合命令中使用别名。
似乎这不仅限于函数,还包括 if 语句。整个 if 块被视为一行。为了确保仅在条件为 true 时定义并执行别名,但确保在条件为 false 时甚至不定义别名,解决方案是像这样评估条件两次:
cat alias-before-if.sh
if true ; then
alias foo='echo hi'
fi
if true; then
foo
fi
$ sh alias-before-if.sh
hi
所以我原来的脚本是:
if [ -n "$TERM" ] && [ "$TERM" != "dumb" ] ; then
alias short='long command here'
alias another='very long command here'
# ...
fi
if [ -n "$TERM" ] && [ "$TERM" != "dumb" ] ; then
short
fi