web-dev-qa-db-ja.com

プロセスが実行中かどうかを判断し、それを使用して条件付きシェルスクリプトを作成する方法

プロセスが実行されているかどうかを判断し、bashスクリプトにその条件に基づいて何かを実行させるにはどうすればよいですか?

例えば:

  • プロセスabcが実行されている場合、これを行います

  • 実行されていない場合は、実行します。

107
Nirmik

そのようなことを行うbashスクリプトは次のようになります。

#!/bin/bash

# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern. 

if pgrep -x "gedit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi

このスクリプトは、プログラム「gedit」が実行されているかどうかを確認するだけです。

または、次のようにプログラムが実行されていない場合にのみ確認できます。

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi
165
John Vrbanac

ps aux | grep abcpgrep abcのようなものを使用するソリューションには欠陥があります。

どうして?

特定のプロセスが実行されているかどうかを確認していないため、abcに一致する実行中のプロセスがあるかどうかを確認しています。すべてのユーザーは、abc(またはその名前または引数にabcを含む)という名前の実行可能ファイルを簡単に作成して実行でき、テストで誤検知が発生します。検索を絞り込むためにpsgrep、およびpgrepに適用できるさまざまなオプションがありますが、それでも信頼できるテストは得られません。

では、特定の実行中のプロセスを確実にテストするにはどうすればよいですか?

それは、テストの対象によって異なります。

サービスabcが実行されていることを確認し、実行されていない場合は開始する

これがinitとupstartの目的です。サービスを開始し、そのpidがpidfileに保存されるようにします。 (initまたはupstartを介して)サービスの再起動を試行すると、pidfileがチェックされ、存在しない場合は開始されるか、既に実行されている場合は中止されます。これはまだ100%信頼できるものではありませんが、あなたが得るのと同じくらい近いです。

ゲームサーバーがまだ実行されているかどうかを確認するにはどうすればよいですか... を参照してください。

abcは私のスクリプトです。スクリプトのインスタンスが1つだけ実行されていることを確認する必要があります。

この場合、ロックファイルまたはロックディレクトリを使用します。例えば。

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

ロックの他の方法については、 Bash FAQ 45​​ を参照してください。

35
geirha

これは私が使用するものです:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

簡単な英語: 'pgrep'が0を返す場合、プロセスは実行中です。それ以外の場合は実行されていません。


関連資料:

Bashスクリプト:: 文字列比較

Ubuntuマニュアル pgrep

18
Zuul

通常、スクリプトにpidof -x $(basename $0)があり、既に実行されているかどうかを確認します。

5
Rommel Cid

@ rommel-cidのアイデアをリフティングするには、||でpidofを使用できます。 (||)プロセスが存在しない場合はコマンドを実行し、プロセスが存在する場合は&&を実行して、if/then/else条件をすばやく作成します。たとえば、実行中のプロセス(プロセス名が "chrome"のmy chromeブラウザ)と、存在しないプロセスのテストを行うものがあります。 1>/dev/nullを使用して標準出力を抑制し、印刷されないようにしました。

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$
2
yuvilio

チェックする必要のあるバイナリがシステム全体にインストールされていないため、「単純な」ソリューションはどれも役に立ちませんでした。したがって、ps -ef | grepアプローチを使用する必要があるパスでチェックする必要があります。

app="$_sdir/Logic 1.2.18 (64-bit)/Logic"

app_pid=`ps -ef | grep "$app" | awk '{print $2}'`

if `ps -p $app_pid > /dev/null`; then
    echo "An instance of logic analyzer is appear to be running."
    echo "Not starting another instance."
    exit 5
else
    Nohup "$app" &> /dev/null &
fi
1
ceremcem
## bash

## function to check if a process is alive and running:

_isRunning() {
    ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}

## example 1: checking if "gedit" is running

if _isRunning gedit; then
    echo "gedit is running"
else
    echo "gedit is not running"
fi

## example 2: start lxpanel if it is not there

if ! _isRunning lxpanel; then
    lxpanel &
fi

## or

_isRunning lxpanel || (lxpanel &)

pgrep -x lxpanelまたはpidof lxpanelは、無効(ゾンビ)であってもlxpanelが実行されていることを報告します。稼働中のプロセスを取得するには、psおよびgrepを使用する必要があります

0
Bach Lien

あなたの問題について最初に思いついたのは:
ps aux | grep -i abcは、実行中のプロセスの詳細を表示します。実行する行数または時間を一致させ、ゼロまたは他の操作と比較することができます。上記のコマンドを実行すると、少なくとも1行の出力が表示されます。つまり、th grepコマンドによって作成されたプロセスの詳細が表示されます。
これは単純なハックとして行う必要があります。それをbashスクリプトに入れて、役立つかどうかを確認します。

0
drake01

start-stop-daemonを使用:

/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2

通常のユーザーとして機能します。

0

@John Vrbanacによって投稿された受け入れられた回答は私には役に立たず、@ geirhaによって投稿された回答は元の質問に答えないことがわかりました。

John Vrbanacのソリューションは、PHPプロセスが実行されているかどうかを確認できませんでした。CentOS7を実行しています。

@geirhaの答えは、インスタンスが別のインスタンスを開始する前に既に実行されていないことを確認するだけです。これは元の質問ではなく、元の質問はプロセスが実行されているかどうかを確認することでした。

ここに私のために働いたものがあります:

プロセスのプロセス名に「Jane」という文字列が含まれていたとします。これにより、実行中かどうかがわかります。これは、BASHおよびPHPスクリプトに対して機能します。

ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
    echo "It's running"
else
    echo "It's not running"
fi
0
Wayne Workman