プログラムを実行する方法の正確な1つのインスタンスです。または、特定の実行プログラムをテストする方法

プログラムを実行する方法の正確な1つのインスタンスです。または、特定の実行プログラムをテストする方法

プログラムの1つのインスタンスをプロセスとして実行するには?または、実行中のプログラムが存在するかどうかをテストする方法は?

ポータブル方法が好ましい。

答え1

(名前付き)パイプの書き込み可能性をテストし、適切なプログラミングを使用して実行中のプログラムインスタンスの存在をテストできます。

ファイル名を/tmp/fifo-myappFIFOファイルの名前で予約するとします(それぞれのアプリケーション用にカスタマイズする必要があり、通常は一部のアプリケーション固有のフォルダにあり、絶対パスで指定されています)。

ファイル1:test-wr-fifo

#!/bin/sh
# invocation: test-wr-fifo <timeout>

timeout="${1:=3}"

if ! [ -p "/tmp/fifo-myapp" ] ; then
    rm -f "/tmp/fifo-myapp"
    mkfifo "/tmp/fifo-myapp"
fi

{ sleep "$timeout" ; kill -s 0 $$ && kill -s TERM $$ ; } &
exec 3>"/tmp/fifo-myapp"

fifo が開いておらず、指定されたタイムアウトに達すると、プログラムは障害状態で終了します。

ファイル2:single-inst-prog

#!/bin/sh

exec 3<"/tmp/fifo-myapp"

### Application Code ###

これはインスタンスが1つだけ必要なプログラムです。

移動するsingle-inst-prog

./test-wr-fifo || ./single-inst-prog &

これは、FIFOブロックの一方の端を開くまで(O_NONBLOCKがクリアされた場合)、もう一方の端も開くために機能します。 FIFOからデータを読み書きしないために動作するため、EOF条件とSIGPIPEは決して動作しません。信号を送信しました。

答え2

mv私はファイルロック時に競合状態を常に警戒しているので、原子的であるため、特に名前付きファイルを使用します。

通常、プロセスは永続ファイル名を使用します(たとえば/tmp/locks/myProcess.lock、ロックを取得したいすべてのプロセスは名前を(シェルとC/tmp/locks/myProcess.lock.myPIDで使用されている)に変更しようとします。その後、個人名が現在存在することを確認できます。必要に応じてループ/スリープ状態になります。mv(1)rename(2)

注意を払うと、プロセスはロックファイルにログを追加できます(ロックが最初に試行された時間、成功した時間、および解放された時間)。

もちろん、成功後にのみログを記録できるので、最初の試行時間を覚えておく必要があります。また、過剰な待ち時間を監視し、調査警告を発生させる可能性があります(他のプロセスのコピーが失敗し、ロックを解除するonExitがない可能性があります)。

答え3

これは xmessage の例です。これがあなたに効果があるかどうかはわかりませんが、試してみることができます。

#!/bin/sh
xmessage 'hello this is the first xmessage' &
last=$(ps -a | grep '[ ]xmessage$' | awk '{print $1}')
sleep 1
if test $(($(date +%s) % 2)) -eq 0
  then
    kill $last
fi
sleep 1
if ! ps -p $last >/dev/null
  then
    xmessage 'Hi, this is the second xmessage. Visible only if the first is close!' &
fi

関連情報