Subshel​​lバックグラウンドプロセスpidを変数に割り当てる

Subshel​​lバックグラウンドプロセスpidを変数に割り当てる

私は現在サブシェルでバックグラウンドプロセスを開始していますが、サブシェルの範囲外の変数に対応するpid番号を割り当てる方法がわかります。
私は他の多くのことを試しましたが、MYPID常に同じままです0

MYPID = 0;
({ sleep 2 & }; $MYPID=$!)
({ sleep 2 & }; echo $!) > $MYPID

値を返す唯一の方法は次のとおりです。

$MYPID=$({ sleep 2 & }; echo $!)

ただし、これはバックグラウンド処理コマンドを削除し、2秒後にのみ結果を返します。

ベストアンサー1

bashインタラクティブでない場合は、ジョブの状態を印刷しないでください。

これが実際にインタラクティブな場合は、bash次のようにできます。

{ pid=$(sleep 20 >&3 3>&- & echo "$!"); } 3>&1

sleepパイプに変数を提供する代わりに、stdoutが前の位置に移動したいと思います$pid。だから私たちは保存外のファイル記述子3()3>&1のstdoutをsleep内部コマンドの代替として復元します。したがって、提供されたパイプに開いているファイル記述子がないため、終了pid=$(...)したら返されます。echo$pid

ただし、サブシェルから始まるので(ここではコマンドの置き換え)、sleep別のプロセスグループでは実行されません。したがってsleep 20 &、たとえばターミナルI / Oとは異なる動作をします。

おそらくより良い方法は、生成をサポートするシェルを使用することです。認識されないzsh実行できるタスクなどのバックグラウンドタスク:

sleep 20 &! pid=$!

を使用すると、bash次のように大まかに計算できます。

{ sleep 20 2>&3 3>&- & } 3>&2 2> /dev/null; pid=$!; disown "$pid"

bashstderrに出力します[1] 21578。したがって、/ dev / nullに再度リダイレクトする前にstderrを保存し、sleepコマンドに対して復元します。これにより but の stderr[1] 21578に行くのが普段通りに進みます。/dev/nullsleep

すべてを/dev/nullにリダイレクトするには、次のようにします。

{ apt-get update & } > /dev/null 2>&1; pid=$!; disown "$pid"

標準出力のみリダイレクト:

{ apt-get-update 2>&3 3>&- & } 3>&2 > /dev/null 2>&1; pid=$!; disown "$pid"

おすすめ記事