ジャンプサーバーで実行されるbashシェルスクリプトを作成しています。検索する文字列を表す1つのパラメータがあります。引数は、ディレクトリ内の複数のファイルから検索引数を検索し、結果を引用符で囲んだ文字に変換するwc -l
` - 周辺コマンド(コマンドの置き換え)に提供されます。コマンド引数として渡された文字列:
ssh server "[grep command]"
sshコマンドは、確認したいすべてのサーバーを通過するループで実行されます。
各要素が適切な時間まで評価されないように、すべての参照を正しく作成することは大きな苦痛でしたが、この狂ったことはほとんどうまくいきました。
すべてが正しいサーバーにSSHで接続されていますが、サーバーでコマンドが実行されると、結果は次のようになります。
bash: /bin/echo "26520 instances of [xyz]": No such file or directory
26520は成功した操作の結果です。
/bin/grep xyz /path/to/logfiles/*access*|wc -l
これはsshを介してコマンドの一部として渡されます。
ssh server [command]
実際にリモートサーバーの1つにSSHで接続して実行すると、
$ /bin/echo "26490 instances of [xyz]"
26520 instances of [xyz]
もちろん、bashには問題はありません。
実際にリモートサーバーの1つにSSHで接続して実行すると、
$ /bin/echo "`/bin/grep xyz /path/to/logfiles/*access*|wc -l` instances of [xyz]"
26520 instances of [xyz]
Bashにも問題はありません。
ただし、コマンドがsshを介して渡されると、この問題が発生します。 grepコマンドを実行して正しい結果を生成しても
bash: /bin/echo "26520 instances of [xyz]": No such file or directory
Bashは正確に何に反対ですか?この問題をどのように解決できますか?
修正する:簡単にするために、単一のコマンドラインで問題を再現できることがわかりました。地元のサーバー、スクリプト、変数置換などによるすべての複雑さを抽象化します。
$ ssh {remoteserver} "echo `/bin/grep xyz /path/to/logfiles/*access*|wc -l`"
grep: /path/to/logfiles/*access*: No such file or directory
26520
bashはそのようなファイルがないと再び文句を言い、その後(まだ存在しています)、grepコマンドを実行して正しい結果を印刷します。
コマンドライン引数を解析した後、ファイルの内容をsshにパイピングした後、リモートサーバー上のすべてのコマンドをローカルサーバー上のファイルに書き込むスクリプトを再構築して、問題を解決しました。
echo ... > commandfile
cat commandfile | ssh -T ${SERVER}
私もやってみた<
しかし、私はまだbashオブジェクトが何であるかを知りたいです。
答え1
走る
ssh {remoteserver} "echo `/bin/grep xyz /path/to/logfiles/*access*|wc -l`"
サブコマンドがリモートシステムではなくローカルシステムで実行されるようにします。これは、以下を使用して簡単に確認できます。
$ ssh host "echo `hostname`"
the local hostname
リモートサーバーでサブコマンドを実行するには、アポストロフィを使用します。
$ ssh host 'echo `hostname`'
the remote hostname
しかし、アップデートエラーは元のエラーとは異なります...
答え2
ssh server "[grep command]"
変数とコマンドの置換(、、、)は二重引用符で囲まれているため、にまたはが表示されると、呼び出し前にローカルシェルで行われます。その後、交換が実行されると(ローカルでコマンドを実行する)、リモートホストから文字列を呼び出します。$variable
$(command)
`command`
$
`
[grep command]
ssh
grep
ssh
echo
リモートホストで実行するコマンドを一重引用符(アポストロフィなど)で囲みます。
ssh server '[grep command]'
簡単にするために、コマンドに一重引用符を含めないでください。一重引用符が本当に必要な場合'\''
(単一引用符、バックスラッシュ、一重引用符、一重引用符)として含めることができます。