sshがローカルではなくリモートシステムでコマンドを実行するように強制する方法

sshがローカルではなくリモートシステムでコマンドを実行するように強制する方法

SSHに次のスクリプトでいくつかのコマンドを実行させました。

#!/bin/bash

REMOTEUSER=$1
REMOTEHOST=$2    
newVh=$3

ssh "$REMOTEUSER"@"$REMOTEHOST" << EOF

cd

if [ ! -d "/data/web/someDirectory" ]
then
  echo -e "There is no vhost setup for someDirectory"
  exit 1
fi


if [ ! -d "git" ]
then
  echo -e "Home git directory not found. Creating it now."
  mkdir git
fi

if [ ! -d "git/$newVh.git" ]
then
  echo -e "Bare git repository not found for $new. Creating it now."
  mkdir git/"$newVh".git
  git init --bare git/"$newVh".git
fi


EOF

うまく動作し、私が欲しいものを行います。リモートコンピュータにRuby gemがインストールされているか確認しようとしていますがcompass、なければインストールしたいと思います。スクリプトの下部に次の行を追加しました。

.
.
.
if [ `gem list compass -i` == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi


EOF

しかし`gem list compass -i`、。私のローカルコンピュータで事前に評価しました(コンパスがインストールされています)。gem list compass -i出力を表示するために引用符なしでスクリプトを実行しても結果が返されますが、trueこれは間違っています。成功せずに複数のsでコマンドをエスケープしようとしました\

私は2つの問題があると思います:

スクリプトの他のコマンド(mkdir、etc...)がリモートシステムでは正常に動作しますが、機能しcdないのはなぜですか?git initgem list

このコマンドをエスケープしてリモートで実行するにはどうすればよいですか?

答え1

元のコードの問題は、コマンドが実行される前にコマンド置換式(バックティックで示されている)が評価されることですssh。他の状況では、here-docでパラメータ拡張を防ぐためにhere-docキーワード(例: "EOF")を引用することを検討することができますが、この場合は実際にはクライアント側のパラメータ置換で操作を実行したいと思います。したがって、ここで解決策はコマンドの置換を避けることです。この試み:

if [ \`gem list compass -i\` == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

エスケープされたバックティックは、コマンド置換が評価されないようにします。

また、コマンド置換のバックティック構文は従来の機能と広く見なされており、現在ではドル記号の構文が一般的に好ましいことに言及したいと思います。ドル記号の構文を使用した上記のコードスニペットは次のとおりです。

if [ \$(gem list compass -i) == 'false' ]
then
  echo -e "Compass not installed... Installing it now."
  gem install compass -V
fi

これら2つの表記法の違いの詳細については、次のStackExchangeの記事を参照してください。

また、見ることができますコマンド置換のGNU Bashのマニュアルページ

そしてまだそこにいるリダイレクトのGNU Bashのマニュアルページ

ここのマニュアルの次のサブセクションに特別な注意を払ってください。

3.6.6 ここに文書化

このタイプのリダイレクトは、行に次の項目のみが含まれるまで、現在のソースから入力を読み取るようにシェルに指示します。言葉(末尾の空白なし)が表示されます。その時点まで読んだすべての行は、標準入力(またはファイル記述子)として使用されます。NもしN指定)をコマンドとして使用します。

この文書の形式は次のとおりです。

[n]<<[-]word
    here-document
delimiter

パラメータおよび変数拡張、コマンド置換、算術拡張、またはファイル名拡張を実行しません。言葉。どんな部分でも言葉引用されたので区切り記号引用符を削除した結果です。言葉、ここのドキュメントの行は拡張されません。もし言葉引用符がない場合、here-documentのすべての行はパラメータ拡張、コマンド置換、および算術拡張を受け取り、文字シーケンス\ newlineは無視され、「\」、「$」、および「文字を引用するには '\'を使用する必要があります」。

リダイレクト演算子が「<<-」の場合、すべての先行タブ文字が入力行と包含行から削除されます。区切り記号。これにより、シェルスクリプトのドキュメントを自然にインデントできます。

関連情報