2

重複の可能性:
一度に実行されるシェル スクリプトのインスタンスが 1 つだけであることを確認する手っ取り早い方法

私はシェルスクリプトが初めてです。

私がしたいのは、スクリプトの複数のインスタンスを実行しないようにすることです。

このシェルスクリプトcntps.shがあります

#!/bin/bash
cnt=`ps -e|grep "cntps"|grep -v "grep"`
echo $cnt >> ~/cntps.log
if [ $cnt < 1 ];
then 
    #do something.
else
    exit 0
fi

このように実行すると$./cntps.sh、2がエコーされます

このように実行すると$. ./cntps.sh、0がエコーされます

で実行するとcrontab、3がエコーされます

誰かが私になぜこれが起こっているのか説明できますか? また、スクリプトの複数のインスタンスを実行しないようにする適切な方法は何ですか?

4

3 に答える 3

2

コマンドを少し変更psしてログファイルに出力し、何が起こっているかを確認できるようにしました。

cnt=`ps -ef| tee log | grep "cntps"|grep -v "grep" | wc -l`

これは私が見たものです:

32427 -bash
  20430 /bin/bash ./cntps.sh
    20431 /bin/bash ./cntps.sh
      20432 ps -ef
      20433 tee log
      20434 grep cntps
      20435 grep -v grep
      20436 wc -l

ご覧のとおり、私の端末のシェル(32427)は、スクリプトを実行するための新しいシェル(20430)を生成します。次に、スクリプトはコマンド置換(`ps -ef | ...`)のために別の子シェル(20431)を生成します。

したがって、2つのカウントは次の理由によるものです。

  20430 /bin/bash ./cntps.sh
    20431 /bin/bash ./cntps.sh

いずれにせよ、これは1つのプロセスのみが実行されていることを確認するための良い方法ではありません。代わりに、このSOの質問を参照してください。

于 2012-11-01T10:31:53.697 に答える
1

まず、pgrepこの方法ではなく使用することをお勧めします。wc -l次に、スクリプトからインスタンスの数を数えるためのa が欠落していると思います

あなたのカウントの問題への答えとして:

このように実行すると$./cntps.sh、エコーします2

これは、バックティック コール:ps -e ...が呼び出されたサブシェルをトリガーしてcntps.shおり、これにより 2 つのアイテムがトリガーされるためです。

このように実行すると$. ./cntps.sh、エコーします0

これは、実行していないために発生しますが、実際には現在実行中のシェルにソースしています。これにより、名前で実行されているスクリプトのコピーがなくなりますcntps

で実行するとcrontab、エコーします3

呼び出しから 2 つ、生成される crontab 呼び出し自体から 1 つsh -c 'path/to/cntps.sh'

単一インスタンスのシェル スクリプトを実行する方法については、この質問を参照してください。

于 2012-11-01T10:18:59.187 に答える
0

「ロック」ファイルをミューテックスとして使用します。

if(exists("lock") == false)
{
    touch lock file // create a file named "lock" in the current dir
    execute_script_body // execute script commands
    remove lock file // delete the file
}
else
{
    echo "another instance is running!"
}

exit
于 2012-11-01T10:39:26.610 に答える