`ssh foo`“` 没有加载远程别名?

`ssh foo`“` 没有加载远程别名?

摘要:为什么会失败

$ 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) 提供几乎相同的资源。另一个集群(不幸的是,我也必须在其上工作)有单独管理的服务器,因此我习惯于这样做,例如,

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)

当我以交互方式进入服务器时,使用别名可以很好地解决这些安装差异,但当我尝试编写 ssh 命令脚本(如上所述)时会失败;即,

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

调用我的R远程主机别名= foo,但是

# scripting
$ ssh foo 'R --version'

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

答案1

来自bash手册页:

当 shell 不是交互式的时,别名不会展开,除非使用 shopt 设置 expand_aliases shell 选项(参见下面 Shell 内建命令 下对 shopt 的描述)。

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

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

答案2

Andrew 的回答解释了原因。我只给出一个解决方案:

不要使用aliases,而要使用他们的function equivalents

例如:

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

用这个:

function ll{ ls -lah "$@" }

相关内容