私はそのようなコマンドを多く使用するプラットフォームで作業しています:ssh [email protected] 'curl http://some_server/script.sh | bash'
これはスクリプトをリモートで実行するのに非常にクリーンで便利ですが、スクリプトの出力/終了コードを取得する方法がわかりません。だれでも、スクリプトが適切に実行されたことを確認するために何かを理解できます(ホストがsshの観点から起動した場合)。
@Zoredacheが指摘するように、ssh
はリモートコマンドのステータスを独自の終了ステータスとして中継するため、エラー検出はSSH経由で透過的に機能します。ただし、例では2つの重要な点について特別な考慮が必要です。
まず、curl
は非常に寛大で、多くの異常な状態を成功として扱います。例えば、 curl http://serverfault.com/some-non-existent-url-that-returns-404
の実際の終了ステータスは0です。この動作は直観に反するものです。これらの条件をエラーとして扱うために、私は-fsS
フラグ:
--fail
フラグは、障害が発生したときに出力を抑制し、bash
がWebサーバーの404エラーページをコードのように実行する機会を与えないようにします。--silent --show-error
フラグを一緒に使用すると、妥当な量のエラー報告が提供されます。 --silent
は、curl
からのすべての注釈を抑制します。 --show-error
STDERRに送信されるエラーメッセージを再度有効にします。次に、パイプがあります。つまり、最初のコマンドまたは2番目のコマンドのいずれかで障害が発生する可能性があります。 bash(1) のパイプラインに関するセクションから:
pipefail
オプションが有効になっていない限り、パイプラインの戻りステータスは、最後のコマンドの終了ステータスです( Set Builtin を参照)。pipefail
が有効になっている場合、パイプラインの戻りステータスは、ゼロ以外のステータスで終了する最後の(右端の)コマンドの値、またはすべてのコマンドが正常に終了した場合はゼロです。
注意事項:bash
のドキュメントは、パイプを使用してbash
に関係するのではなく、(私は)リモートユーザーのログインシェルであり、したがって、リモートコマンドラインを解釈し、パイプラインの実行を処理するプログラムになります。ユーザーが別のログインシェルを使用している場合は、そのシェルのドキュメントを参照してください。
具体的な例として、
( echo whoami ; false ) | bash
echo $?
出力を生成します
login
0
パイプラインの最後のbash
がfalse
によって返されるエラーステータスをマスクすることを示しています。 whoami
が正常に実行される限り、0を返します。
対照的に、
set -o pipefail
( echo whoami ; false ) | bash
echo $?
収量
login
1
パイプラインの前半での障害が報告されるようにします。
それをすべてまとめると、ソリューションは
ssh [email protected] 'set -s pipefail ; curl -fsS http://some_server/script.sh | bash'
これにより、次のいずれかがゼロ以外の値を返した場合に、ゼロ以外の終了ステータスが取得されます。
ssh
curl
bash
さらに、curl -fsS
は異常なHTTPステータスコードを検出し、次のことを行います。
bash
にパイプされないようにします。それはすべて、script.shがその仕事について何をするか/行うかによって異なります。冗長である(出力があるものを実行する)場合は、sshストリームのSTDOUT/STDERRで確認できます。もしそうなら、そうするようにそれを修正しません。
SSHが戻ると、スクリプトから終了コードが発行されます。
ssh user@Host 'echo "exit 2" | bash' ; echo $?
をお試しください。 2
の値が返されます。
スクリプトに適切なエラーチェックをたくさん書いて、スクリプトが有用なエラーと終了コードで終了することを確認してください。エラーがない場合は、スクリプトがゼロ以外の終了コードを返すことを確認してください。
ここにあなたが試すことができるいくつかのオプションがあります。
別の方法は、エコー$を使用することでしょうか?スクリプトが実行された直後に実行し、
# ssh [email protected] 'curl http://some_server/script.sh | bash; echo $?'
これにより、スクリプトの終了ステータスがわかります。または終了ステータスが0の場合にのみテキストを入力します
# ssh [email protected] 'curl http://some_server/script.sh | bash && echo "Script Completed!"'
「スクリプトが完了しました!」と表示されます。成功した実行時。または終了ステータスが0でない場合にのみエラーコードを表示する
# ssh [email protected] 'curl http://some_server/script.sh | bash || echo "Script Failed: $?"'
これにより、「スクリプトが失敗しました:」と表示されます。@ Zoredacheによって提案されているように、スクリプトに複数の終了ステータスを追加すると、問題の原因を特定するのに役立ちます。