ShellScript
SSH

sshでリモートシェル実行時に``で括ったコマンドを使う

More than 1 year has passed since last update.

あるサーバからリモートにあるサーバにログインし、コマンドを実行したい、ということが時々あるかと思います。
単純なコマンドの場合はssh ユーザ名@ログイン先 実行コマンドとして直接書けばよいのですが、複数の処理を行おうとした場合、この方法では可読性が犠牲になります。
そのため、対策として例えば次のように書くと多少長くなっても読みやすいです。

下記はリモートのhomeディレクトリにあるファイル及びディレクトリの数を数えて、1以上なら"not empty!"と出力するシェルスクリプトです。

sample.sh
#!/bin/bash

cat << EOF > "cmd.txt"
  if [ `ls -1U "/home/" | wc -l` -gt "0" ]; then
    echo "not empty!"
  fi
EOF
cmd=`cat "cmd.txt"`
rm "cmd.txt"

ssh root@127.0.0.1 "${cmd}"

ところで、上記の通りに実行すると、想定通りに動きません。if文の中のlswcがローカルで実行されてしまい、${cmd}に格納される値は次のようになってしまいます。

  if [ 1 -gt "0" ]; then
    echo "not empty!"
  fi

リモートで``に囲まれたコマンドを実行するにはどうしたらよいでしょうか。

sample_fixed.sh
#!/bin/bash

echo '
  if [ `ls -1U "/home/" | wc -l` -gt "0" ]; then
    echo "not empty!"
  fi
' > script.sh

ssh root@127.0.0.1 'bash -s' < script.sh

このようにすれば可能です。
bash -sによって、標準入力から実行するコマンドを流し込めます。

尚、上記の例で変数を使用する場合は次のようにします。

sample_fixed_improved.sh
#!/bin/bash

echo '
  if [ `ls -1U "/home/" | wc -l` -gt "0" ]; then
    echo "'${HOME}' is not empty!"
  fi
' > script.sh

ssh root@127.0.0.1 'bash -s' < script.sh

${HOME}変数の前後にシングルクオート(')を加えることにより、
変数の中身を出力するようにしています。

参考

  • Execute inside of back-quote command on ssh 自力で解決ができず、StackOverflowにて質問したところ、回答を得られました。回答内容に変数利用のための記述を追加してこの記事を書いています。