要約:なぜこれが失敗するのか
$ 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つのクラスターの(ルートレス)ユーザーです。 1つは環境モジュールを使用するため、そのクラスター上の任意のサーバーは(module add
を介して)ほぼ同じリソースを提供できます。残念ながら私も作業しなければならないもう1つのクラスターでは、サーバーが個別に管理されているため、次のような作業を行う習慣があります。
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/>"
にエイリアスをリモートホストにロードさせるにはどうすればよいですか?
bash
のマンページから:
シェルが対話型でない場合、shoptを使用してexpand_aliases Shellオプションが設定されていない限り、エイリアスは展開されません(以下のShell BUILTIN COMMANDSのshoptの説明を参照してください)。
必要がある shopt -s expand_aliases
リモコンで.bashrc
s、そしてそれらの.bashrc
非対話型の場合に処理されます。デフォルト .bashrc
ディストリビューションには、非対話型の場合に早期に終了するためのチェックが含まれる場合があります。 Ubuntuは以下を使用します:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
アンドリューの答えはその理由を説明しました。私はもう1つの解決策を与えるだけです:
aliases
を使用する代わりに、function equivalents
を使用してください。
例えば:
使用する代わりに:alias ll='ls -lah'
これを使って:
function ll{ ls -lah "$@" }