現在、サブシェル内でバックグラウンドプロセスを開始していますが、そのpid番号をサブシェルスコープ外の変数に割り当てるにはどうすればよいですか?
さまざまな方法を試しましたが、MYPID
は常に0
に設定されたままです。
MYPID = 0;
({ sleep 2 & }; $MYPID=$!)
({ sleep 2 & }; echo $!) > $MYPID
値を返す唯一の方法は次のとおりです。
$MYPID=$({ sleep 2 & }; echo $!)
ただし、これによりバックグラウンドプロセス命令が破棄され、2秒後にのみ結果が返されます。
bash
は、非対話型の場合、ジョブのステータスを出力しないでください。
それが実際にインタラクティブなbash
の場合は、次のことができます。
_{ pid=$(sleep 20 >&3 3>&- & echo "$!"); } 3>&1
_
sleep
のstdoutは、_$pid
_変数にフィードするパイプではなく、以前の場所に移動する必要があります。したがって、outer stdoutをファイル記述子3(_3>&1
_)に保存し、コマンド置換内でsleep
用に復元します。したがって、_$pid
_をフィードするパイプに開いているファイル記述子が残っていないため、pid=$(...)
はecho
が終了するとすぐに戻ります。
ただし、サブシェル(ここではコマンド置換)から開始されるため、そのsleep
は別のプロセスグループでは実行されないことに注意してください。したがって、たとえば端末へのI/Oに関しては、_sleep 20 &
_を実行することと同じではありません。
おそらく、スポーンをサポートするシェルを使用する方が良いでしょうdisownedzsh
のようなバックグラウンドジョブを実行できます。
_sleep 20 &! pid=$!
_
bash
を使用すると、次のように概算できます。
_{ sleep 20 2>&3 3>&- & } 3>&2 2> /dev/null; pid=$!; disown "$pid"
_
bash
は_[1] 21578
_をstderrに出力します。繰り返しになりますが、/ dev/nullにリダイレクトする前にstderrを保存し、sleep
コマンド用に復元します。このように、_[1] 21578
_は_/dev/null
_に移動しますが、sleep
のstderrは通常どおりに移動します。
とにかくすべてを/ dev/nullにリダイレクトする場合は、次のようにするだけです。
_{ apt-get update & } > /dev/null 2>&1; pid=$!; disown "$pid"
_
Stdoutのみをリダイレクトするには:
_{ apt-get-update 2>&3 3>&- & } 3>&2 > /dev/null 2>&1; pid=$!; disown "$pid"
_
2行目が機能しない
({ sleep 2 & }; $MYPID=$!)
( ... )
サブシェルをフォークすると、MYPIDが設定され、サブシェルが終了すると、その値が失われます。
3行目も機能しませんでした
({ sleep 2 & }; echo $!) > $MYPID
$をエコーするだけです!ローカルディレクトリの0という名前のファイルに。
私が提供できる唯一の答えは、一時ファイルを介することです(varはプッシュバックできないため)
( { sleep 100 & } ; echo $! > u ) > /dev/null &> /dev/null
MYPID=$(<u)
u
は任意のファイルに置き換えることができます。