
sleep 10
たとえば、非常に長いコマンドがあるとします。paramiko
Python(特に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シリーズのシェルと互換性がなければなりません。