web-dev-qa-db-ja.com

スクリプト内からプログラムが実行されているかどうかをテストする方法

別のユーザーがbunzipプロセスを開始し、そのbunzipの完了後に実行を開始したいスクリプトがあるとします。スクリプト内からbunzipプロセスが終了したことを確認する最良の方法は何ですか? pidを指定したpsの呼び出し? pgrep bunzip?スクリプトを実行できるかどうかを確認するために5分ごとにチェックするcrontabにスクリプトを投入するとします。また、bunzipは1時間以上実行されており、完了するまでに1時間かかる可能性があるため、bunzipを停止したくないものとします。

私の最初の反応は次のようなものを使用することです

if `ps -p 12938`
    # bunzip is done, execute the code
fi 
    # exit

しかし、もっと良い方法があるかどうか疑問に思っています。また、私はcross-unix ps -pidがどのくらいかわかりません。

5
gabe.

あなたの明白な質問:与えられたPIDでプロセスの存在をテストする

ps -p $pid[〜#〜] posix [〜#〜] であり、最新の非組み込みunixで機能する必要があります( antiques または Minixではありません) または BusyBox )。

特定のPIDによるプロセスがあるかどうかをテストする簡単で移植可能な方法は、kill -0 $pidです。これは、シグナルをプロセスに送信できる場合にのみ機能します(シグナル0は常に配信されるが効果がないシグナルのように動作します)。つまり、killがプロセスの実効UIDで実行されているか、ルートとして実行されています。 killが別のユーザーとして実行されている場合は、「そのようなプロセスがない」(ESRCH)か「操作は許可されていません」(EPERM)のどちらであるかをテストできますが、シェルからは実装のフォーマット方法を知る必要がありますエラーメッセージ。

基本となる設計:プロセスが完了したかどうかのテスト

あなたの提案された設計には大きな欠陥があります:そのPIDがあなたが待っていたbunzipプロセスであるかどうかをどうやって知るのですか?たぶんbunzipが終了し、古いPIDを持つ別のプロセスができました。プロセスの終了を確実に待機できる唯一の場所は、その親です。

より良いアプローチは、非圧縮ファイルの存在と圧縮ファイルの非存在のいずれかでトリガーするか、または非圧縮ファイルが(lsofを使用して)プロセスによって開かれていないことを確認することです。

Psの使用には何の問題もありませんが、これは代替手段です

if [ -e /proc/${PID} -a /proc/${PID}/exe ]
    % process active
else
    % process no longer active
fi
4
frabjous

いくつかの選択肢があります。

  • Psを使用してPIDを探します。ただし、プロセスのPIDを知る必要があります。
  • Psを使用してbunzipを探します。コマンドライン全体を確認する必要があります。
  • Lsofを使用して、ソースファイルがアクセスされなくなったことを確認します。
  • 同じですが、解凍されたファイルがまだアクセスされているかどうかを確認してください。

これらのどれも、本当にばかであるか、きれいではありません。

最も簡単な方法は、ユーザーの手を離れて、解凍を実行してからコードを実行するスクリプトを記述することです。

これが不可能な場合は、ファイルの解凍中にディスク上にpidファイルを作成するスクリプトを作成するようにユーザーに依頼してください。その後、PIDファイルを検索できます。

1
David