1行のbash呼び出しからPIDと戻りコードを取得する

1行のbash呼び出しからPIDと戻りコードを取得する

sleep 10たとえば、非常に長いコマンドがあるとします。paramikoPython(特にsshライブラリ)を使用して他のサーバーで実行しようとしています。

コマンドを開始し、コマンドのPIDを印刷してから、完了するのを待ち、最後にコマンドの終了ステータスを返す1行のコマンドが必要です。

私が今まで試したこと:

bash -c "echo $BASHPID ; exec sleep 10" ; echo $?

これはシェルのPIDを印刷し、長いコマンドに対してexecを呼び出してから待ってから終了ステータスを印刷します。問題は、$BASHPID外部bashシェルのPIDを印刷することです(おそらく、呼び出しがbash -c cmd実際に完全な新しいシェルを生成しないことを示します)。

上記のコマンドを3行で呼び出すと機能します。

bash
echo $BASHPID ; exec sleep 10
echo $?

サブシェルを使用しようとすると、私には効果がありません。

echo $(echo $BASHPID ; exec sleep 10) ; echo $?

これは機能しますが、サブシェルはすべての出力をechoにパイプし、echoはすべてをすぐに印刷します。つまり、$BASHPID省電力モードが完了するまで印刷しません。 PIDはすぐに印刷する必要があります。

答え1

たとえば、実行すると次のようになります。

bash -c "echo $BASHPID; 省電力 10 実行"

または

echo$(echo$BASHPID; 省電力 10 実行)

$BASHPID現在、シェルは、2番目のbash(またはサブシェル)が表示する前に変数を挿入しています。解決策は、現在のシェルがこれらの変数を拡張できないようにすることです。

bash -c 'echo $BASHPID ; exec sleep 10'

答え2

sshこれは、他のシェルを起動せずにすでに実行したシェルコマンドです(リモートユーザーのログインシェルとして解釈されます)。シェルがBourneに似ているか、cshに似ているとします。

echo "$$"; exec sleep 10

それだけで十分です。bashリモートホストにはインストールは必要ありません。sshリモートコマンドの終了ステータスも印刷されずに報告されます。しかし、必ずしなければならない場合は、次のようにすることができます。

sleep 10 & echo "$!"; wait; echo "$?"

$?cshなどのシェルでは機能しません$status

リモートユーザーのログインシェルがBourneのログインシェルに似ていることを保証できない場合は、次のことができます。

exec sh -c 'sleep 10 & echo "$!"; wait; echo "$?"'

このコマンドは、少なくともBourne、csh、およびrcシリーズのシェルと互換性がなければなりません。

関連情報