6

Paramikoを使用してデプロイメントスクリプトを作成しようとしていますが、実行するコマンドの終了コードに問題があります。この回答と同様のコードを使用していますが、もう少し複雑です。基本的に、開発ボックスからジャンプサーバーを経由し、そこから一連の本番マシンに移動する必要があります。そこで、システムユーザー(sudo su --systemuser)に切り替える必要があり、コマンドを実行できます。

問題は、私が理解しているように、sshセッション、ネストされたsshコマンド、そしてsuサブシェルの3つのサブシェルがあることです。Paramikoに内部サブシェルのコマンドの終了コードを返してもらうことができません-最終的に返される終了コードはsshコマンドの終了コードになると思います。この問題は実際にはParamikoに固有のものではないと思います-SSHプロトコルはこの種の使用法もサポートしていますか?

私は現在常に実行しています:

(my command); echo "Process terminated with exit code $?"

次に、これをクライアントで解析しますが、かなり醜いです-より良い方法はありますか?

4

2 に答える 2

8

最終的に返される終了コードは、sshコマンドの終了コードになると思います。この問題は実際にはParamikoに固有のものではないと思います-SSHプロトコルはこの種の使用法もサポートしていますか?

はいといいえ。

終了ステータスは常に返されますが、思った場所からではない場合があります。を呼び出すinvoke_shell()と、リモートプロセスはシェル(おそらくbash)になります。exit_status受け取るのはそのシェルからのものであり、実行したプロセスではありません。Paramiko(またはssh実装)は、コマンドの終了ステータスを返すことができます。これは、終了ステータスがそのリモートシェルの外部に表示されることがないためです。終了ステータスを決定し、シェルを終了するのはあなた次第ですexit $EXIT_STATUS(多くの場合exit $?十分です)

コマンドを分割するか、スクリプトでラップしてからexec_command()メソッドを使用できる場合は、正しい終了ステータスに直接アクセスできます。

または、リモートシェルでshellコマンドを使用するexecと、シェルのプロセスがexecによって呼び出されたコマンドに置き換えられ、その終了ステータスが返されます。

これらの3つのメソッドはすべてchannel.exit_status、期待どおりに属性を設定します。

于 2011-03-29T18:01:18.640 に答える
2

'ssh'のマニュアルページに、実行しているプロセスの終了コードが返されると表示されているという問題がありますが、ゼロ以外のエラーコードを返すようには見えません。sshのmanページから:

 The session terminates when the command or shell on the remote machine
 exits and all X11 and TCP/IP connections have been closed.  The exit sta‐
 tus of the remote program is returned as the exit status of ssh.

それは真実ではないようです。

しかし、私はこのようなことを試して、システムで何が起こるかを確認します。

% ssh localhost bash -c "exit 3" ; echo $?
0

同様のコマンドをローカルで実行すると、bashは終了コードを返します。

% bash -c 'exit 3' ; echo $?
3

ただし、sshがコマンドのように見える前に、二重引用符は削除されます。それでは、もっと引用符を試してみましょう。

% ssh localhost bash -c "'exit 3'" ; echo $?
3

ビンゴ。「exit3」は「exit」に変わり、その後にbashコマンドラインで無視された単語が続きました。したがって、bashはコマンド「exit」を実行していました。

私にとって残念なことに、この答え全体は元の質問からの逸脱であり、それ自体で質問として十分なメリットが含まれていないと思います。ですから、二次的な質問(元の質問とは関係ありません)で答えるのを手伝ってくれたみんなに感謝します。

于 2011-03-17T22:37:27.383 に答える