1

コンテクスト:

私が持っていると言う:

(
#outer subshell
    {
    #inner command group, pipe-connected to ensure simultaneous invocation
        do_first_thing
        #die, somehow
    } | { 
    #inner command group, pipe-connected to ensure simultaneous invocation
        sleep 10
        do_second_thing
    }
)
echo "out"

私は外側のサブシェルを持っています(1つである必要はありません。コマンドグループにすることも、完全に削除することもできます)。その中に、同時に呼び出される2つのパイプ接続されたコマンドグループがあります。両方のグループの実行を開始し、最初のグループが終了したら(2番目のグループはまだ実行中です)、行がある場所で外側のサブシェルのsleep実行を停止します。#die, somehow

質問:

#die, somehow行に到達すると、レベル内のすべてが#outer subshell終了し、その後も実行が継続される(つまりout、印刷される)ようにするにはどうすればよいですか?

私が試したこと:

1つの解決策はkill 0、両方の内部コマンドグループから抜け出すために(現在のプロセスグループ内のすべてを強制終了する)を使用することですが、そうするとecho "out"決して起こりません。外側のサブシェルだけでなく、グループ全体が殺されます。

unsetまた、関数を一時的にオーバーライドしてからオーバーライドしようとしましexitたが、それは問題を別の場所にプッシュしているようです。おそらく私はそれを間違っています。私は決してBashの第一人者ではありません。

なんで?

&プロセスをフォークアウトするために使用することは私のシステム(* nixに埋め込まれている)では決定論的に機能しないため、あまり詳細に立ち入ることなく、奇妙なサブシェル接続コマンドグループが必要です。その結果、パイプ接続されたグループは、do_first_thing実行時間が長すぎる場合(上記の例では10秒)にdo_second_thing発生することを保証します。実際のユースケースはかなり複雑ですが、これが問題の根本です。

乾杯!

4

2 に答える 2

0
#!/bin/bash                                                                     
(
  #outer subshell                                                                 
  {
    #inner command group, pipe-connected to ensure simultaneous invocation      
    first_step;
    ps -ef | grep './lol.bash' | awk '{print $2}' | xargs kill;
    #die, somehow                                                           
  } | {
    #inner command group, pipe-connected to ensure simultaneous invocation      
    ./lol.bash;
  }
)
echo "out"

そして lol.bash には睡眠が含まれており、いわゆる「second_step」が含まれています...あまりきれいではありませんが、変わります。

もう1つの方法は、2番目の部分でループを作成することです。これは、ステップ1が完了したかどうかを確認し、完了した場合は終了するか、最初のステップですべてをクリーンアップし、時間が経過した場合.. .

注意:明らかに、すべてのステップで個別のプロセスを起動し、必要なときにそれを強制終了できます...(pidを知る必要があるだけです...)

于 2012-08-13T21:56:08.390 に答える
0

これらの線に沿った構造は適切でしょうか?

touch /tmp/sentinel-file
(do_first_thing; rm /tmp/sentinel-file) &
pid=$!
sleep 10
if [[ -r /tmp/sentinel-file ]]
then
  kill $pid
  rm /tmp/sentinel-file
  do_second_thing
fi

これを複数回実行すると、いくつかの競合状態が発生しますが、いくつかの点で、現在行っていることよりも少しクリーンになる可能性があります。

于 2012-08-13T21:25:13.403 に答える