プロセスがバックグラウンドで既に実行されているかどうかを確認する方法(およびそれに基づいて再実行をスキップする方法)をbashしますか?


11

プロセスがまだ(バックグラウンドで)実行されていない場合に、特定のコマンドのみを実行するbashコマンドラインを作成できますか?

コマンドがすでに実行されているかどうかを確認するにはどうすればよいですか?

&&そのため、間に次のコマンドを追加して、最初のコマンドがtrueの場合にのみ次のコマンドが実行されるようにすることができます)。

*:テスト、決定、発見、発見


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
Rahul Patil 2013年

1
@RahulPatilのpgrep "process_name"代わりに使用できますps | grep | grep
ラッシュ

うーん、忘れた..:D
Rahul Patil

1
「ロック」ファイルを使用しないでください。2回目に起動すると、ロックファイルが消えたときにのみ起動します。
BitsOfNix

:プロセスが存在するかどうかを確認するための最良の方法stackoverflow.com/questions/3043978/...
トレバー・ボイド・スミス

回答:


6

daemontoolsを使用してください。を使用svokして、サービス/デーモン/バックグラウンドプロセスが現在実行されているかどうかを確認できます。

他の方法については、以下を参照してください。


3

私は時々このテクニックを使いました:

$ pgrep <process name> || <process name>

以前は、pgrepこの方法で行われていました:

$ ps -eaf | grep -q <[p]rocess name> || <process name>

少し[p]それはようになりgrep、結果として自分自身を見つけることができません。

$ ps -eaf | grep -q [s]leep || sleep 10

2

独立して存在する同じプロセスの個別のインスタンスを持つことができるため、これは難しい場合があります。たとえば、異なるポートでリッスンしているサーバーや、異なるユーザーとして実行されているサービスなどです。これらのインスタンスを区別するには、それぞれに一意のタグを割り当てる必要があります。タグは多くの場合ファイルですが、抽象的な名前空間のローカルソケット、TCPポートなどにすることもできます。一意の識別子で可能です。タグがファイルの場合は、プロセスID(pidfile)を含む通常のファイル、またはファイルがリッスンしている名前付きパイプまたはソケットなどにすることができます。理想的には、タグはクライアントが接続できるようにする通信エンドポイントですそのプロセスに。

これらのさまざまな種類のタグはそれぞれ、探しているインスタンスが稼働中であるかどうかを確認する方法が異なります。たとえば、ローカルファイルソケットを使用して接続を試み、そのソケットでリッスンしているプロセスがない場合はプロセスを開始します。タグがpidfileの場合は、そのプロセスIDのプロセスがあるかどうかを確認してください。ただし、プロセスが停止した場合、そのIDを再利用した無関係のプロセスが存在する可能性があるため、これは壊れやすいので注意してください。2つのクライアントが短い時間内にプロセスに到達しようとすると、両方ともプロセスが存在しないことに気づき、両方がプロセスを開始しようとする可能性があることに注意してください。この競合状態から適切に保護するのは難しい場合があります。

インスタンスがすべて同じスーパーバイザプロセスによって開始されている場合、インスタンスを管理する方が簡単であり、そのスーパーバイザプロセスは、インスタンスがいつ停止し、それに応じて反応するかを検出します。これを行うことができる多くのサービス監視プログラム

プログラムが既知の通信エンドポイントで応答せず、プログラムがスーパーバイザープログラムによって管理されていない場合、貧しい人のタグはpidfile:プロセスIDを含むファイルです。プロセスを開始するとき、事前に決められた名前でpidをファイルに書き込みます。プロセスが存在する必要がある場合は、pidfileを読み取り、そのpidを持つプロセスがあるかどうかを確認します。プロセスを強制終了したら、pidfileを消去します。監視なしのpidfileの最も顕著な問題は、プロセスが停止した場合、そのpidが無関係なプロセスによって再利用される可能性があることです。少なくともプロセス名またはプロセス実行可能ファイルをチェックして、正しいプロセスと通信していることを確認する必要があります。多くのUNIXバリアントにはpgrepコマンドがあります。pgrep SOMENAME は、名前にSOMENAMEがサブストリングとして含まれているプロセスをリストします。特定のユーザーに制限したり、完全一致を要求したり、「プロセス名」の考えられる概念のどれを使用するかを変更したりするための追加オプションがあります。


1

このアプローチを使用できます:

if [[ -z $(ps -C appname -opid=) ]]; then
    appname && secondapp
fi

1

他のオプション:

  • pgrep -xq processname
    • GNU / Linuxの最初の15文字のみに一致
    • OS Xの祖先は含まれません
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • GNU / Linuxの最初の15文字のみに一致
    • sed 's|.*/||' OS Xのdirname部分を削除します

GNUでは/ Linuxののps -o comm切り捨ては、15個の文字にコマンド名とpgrepし、ps -C最初の15文字だけに一致します。

ps -C (コマンド名の一致)はOS Xではサポートされていません。

OS Xではps -o comm、コマンドの絶対パスをps -co comm出力し、コマンド名のみを出力します。GNUではps -o commコマンド名のみを出力し-c、意味が異なります。

OS Xのpgrepには、bash、Terminal、launchdなどの祖先プロセスが含まれていません-a。GNUのpgrepにはデフォルトでそれらが含まれており、をサポートしていません-a

grep -xそして、pgrep -x意味するものではありません-Fので、使用を-Fxプロセス名が正規表現の文字を含めることができます。


-Cもcygwinでは使用できません:)
n611x007

1

申し訳ありませんが、同じコマンドラインが「ps」の結果に2回表示されるため、これらのソリューションはすべてcontabをサポートしていません。

これが私のものです:

## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ `ps --no-headers -p "$pid" | wc -l` -gt 0 ] ; then
    echo "WARNING : le process $pid tourne deja : $0"
    ps -edf | grep `basename $0` | grep -v grep
    echo "WARNING : Arrêt de cette instance ($$)."
    exit 7
fi
echo $$ >$lock_file

ごめんなさい。contabとは何ですか?cronジョブ内からチェックするということですか?
Anthon、2015

0

バッシュと

#!/usr/bin/env bash

[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name>  <Command here>"; exit 1;  }

ifnotrun(){
        local p=$1
        if ! ps -C "$1" -opid=
        then
                cmd=($@)
                echo ${cmd[@]:1}
        else
                echo "Process \"$p\" Already Running.."
                exit 1
        fi

}

ifnotrun $*

注:- echo出力がOKの場合は削除します。


0

コマンドをbeckgreoudで実行する場合について説明します。「$!」最後のバックグラウンドプロセスのPIDを保存します。したがって、これを使用して、上記の回答に続くプロセステーブルでそれを見つけることができます。

sleep 4 &
ps -ef | grep -w  $!  ...

組み込みコマンド「ジョブ」-これを試してください:

sleep 4&
J=`jobs`
while [ "$J" ]; do
        sleep 1
        jobs # This line flush the jobs' bufer.
        J=`jobs`
done

「&&」オプションについて

&&の代わりに、コマンドwaitを使用します。次の例では、myproc1が終了するまでmyproc2は実行されません。

myproc1 &
wait
myproc2

0

プロセスの状態を取得します。

ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'

参照:

D    uninterruptible sleep (usually IO)
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
T    stopped, either by a job control signal or because it is being traced
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    defunct ("zombie") process, terminated but not reaped by its parent

たとえば、それを使用して、tmuxセッションでsoxプロセスを条件付きで再生または一時停止しました。

/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
  'send -t sox "fg" Enter' \
  'send -t sox C-z'

-1

スクリプト内で使用できます。

if [ `ps -ef | grep "script.sh" | grep -v grep | wc -l` -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.