`ssh foo“<command />”`不加载远程别名?

总结:为什么这会失败

$ ssh foo 'R --version | head -n 1' bash: R: command not found 

但是这个成功了

 $ ssh foo 'grep -nHe 'bashrc' ~/.bash_profile' /home/me/.bash_profile:3:# source the users .bashrc if it exists /home/me/.bash_profile:4:if [ -f "${HOME}/.bashrc" ] ; then /home/me/.bash_profile:5: source "${HOME}/.bashrc" $ ssh foo 'grep -nHe "\WR\W" ~/.bashrc' /home/me/.bashrc:118:alias R='/share/linux86_64/bin/R' $ ssh foo '/share/linux86_64/bin/R --version | head -n 1' R version 2.14.1 (2011-12-22) 

? 细节:

我是2个群集(无根)的用户。 一个使用环境模块,因此该群集上的任何给定服务器都可以提供(通过module add )几乎相同的资源。 另一个集群,我也必须不幸地工作,有服务器单独pipe理,所以我习惯做,例如,

 EXEC_NAME='whatever' for S in 'foo' 'bar' 'baz' ; do ssh ${SERVER} "${EXEC_NAME} --version" done 

这对正常/一致地安装的软件包来说工作正常,但通常(因为我不知道的原因)软件包不是:例如(比较别名以上别名),

 $ ssh bar 'R --version | head -n 1' bash: R: command not found $ ssh bar 'grep -nHe 'bashrc' ~/.bash_profile' /home/me/.bash_profile:3:# source the users .bashrc if it exists /home/me/.bash_profile:4:if [ -f "${HOME}/.bashrc" ] ; then /home/me/.bash_profile:5: source "${HOME}/.bashrc" $ ssh bar 'grep -nHe "\WR\W" ~/.bashrc' /home/me/.bashrc:118:alias R='/share/linux/bin/R' $ ssh bar '/share/linux86_64/bin/R --version | head -n 1' R version 2.14.1 (2011-12-22) 

当我交互式shell到服务器时,使用别名可以很好地处理这些安装差异,但是当我尝试编写脚本ssh命令(如上所述)时失败。 即

 # interactively $ ssh foo ... foo> R --version 

在远程主机= foo上调用R别名,但是

 # scripting $ ssh foo 'R --version' 

没有。 我需要做什么使ssh foo "<command/>"在远程主机上加载我的别名?

bash manpage:

除非使用shopt设置expand_aliases shell选项(请参阅下面的SHELL BUILTIN COMMANDS下的shopt描述),否则在shell不交互时不会扩展别名。

您需要在远程.bashrc shopt -s expand_aliases ,并检查这些.bashrc是否在非交互式时处理。 您的发行版的默认.bashrc可能包括一个检查,以便在非交互式时提前终止,例如Ubuntu使用:

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

安德鲁的回答解释了原因。 我只给一个更多的解决scheme:

而不是使用aliases ,使用它们的function equivalents

例如:

而不是使用: alias ll='ls -lah'

用这个:

function ll{ ls -lah "$@" }