バックグラウンドで自分自身を呼び出し、終了するスクリプトを検出して停止する方法

バックグラウンドで自分自身を呼び出し、終了するスクリプトを検出して停止する方法

ツールのラッパースクリプトを作成しています。ラッパースクリプトは環境を準備し、バックグラウンドでツールを呼び出して終了する必要があります。次のようになります。

#!/bin/bash
export FOO=1
tool "$@" &

ここには素敵なものはありません。ただし、誤ってツール(/usr/bin/tool)を呼び出さなかったが、効果的にラッパースクリプト自体(〜/bin/tool)を呼び出しました。私はそれを知る前にラッパースクリプトを実行しましたが、何も起こりませんでした。少なくとも何も見えません。

なぜ何も起こらないのか知りたいです。スクリプトをもう一度開きます。エラーを確認してください(/usr/bin/toolは呼び出されません)。実際のツールを実行して保存するように変更します。突然、このようなツールが現れました。しばらく考えた後、ラッパースクリプトがバックグラウンドで実行され続けていることに気づきました。実際のツールを呼び出すようにスクリプトを編集すると、次のスクリプト呼び出しですぐにツールを呼び出し、チェーンが停止します。

分割されていないので、分割爆弾ではありません。しかし、これは再帰的な幽霊のようです。自動再帰ラッパーを再作成し、計測を試みました。私の知識は限られています。私は所有者ではありません。私はpsやpgrepのようなツールを使ってみました。私はこのスクリプトに目立つ名前を付けました:pgrep。しかし、pgrepはほとんどの場合何も見ません。ループでpgrepを実行すると、ランアウェイスクリプトが捕捉されることがあります。 10秒に一度ずつくらい?私は統計をしていません。

再帰的なゴーストスクリプトは無害です。リソースをほとんど食べません。おそらく唯一の顕著な効果は、PIDが急激に上昇することです。なぜなら、すべての新しい呼び出しは新しいPIDを取得するからです。

バックグラウンドで自分自身を呼び出し、終了する暴走再帰ゴーストスクリプトを検出して停止する方法は?

再現する方法は次のとおりです。

  1. woop以下を使用して呼び出されるスクリプトを作成します。

     #!/bin/sh
     ./woop &
    
  2. 2つの端末を開き、テキストエディタでスクリプトを開きます。

  3. 端末で実行してください./woop。目に見える何も起こらないことに注意してください。プロンプトがすぐに返されます。

  4. 2番目の端末で実行してくださいwhile true; do pgrep -fa woop; done。約10秒ごとに結果が表示されます。

  5. テキストエディタで行を別のものに./woop &変更して保存します。最初の端末()./woops &のエラーに注意してください。./woop: line 2: ./woops: No such file or directory

  6. 結果が見つからないという通知が 2 番目の端末に表示されます。

答え1

使用forkstat利用可能な場合、プロセスが実行中かどうかを示す良い表示です。たとえば、

forkstat -e fork

確実な場合は、次のいずれかまたはすべてを実行してください。

  • chmod -x /path/to/file
  • mv ...
  • rm ...

オプションでこの-Sフラグを使用します(簡単な統計は次のとおりです)。

$ forkstat -S
... loads of lines
^C
 Fork     Exec     Exit  ...   Total Process
11546    11532    11547  ...   34625 /bin/bash - ./woop
...

関連:


関連情報