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


108

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

例えば:

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

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


1
以下のソリューションはいずれもプロセスの状態を考慮していないことに注意することが重要です。私の質問の 1つに対するコメントが私をここに連れてきましたが、それに対する答えは、zombieプロセスのようなプログラムの異なる状態に私を惹きつけました(「実行中」プロセスとは言いません)。何の完全なリストSTAT列の値は、出力の中にps、あることを示し、ここでこれを収容し、答えを書き、または自分自身を編集するに傾斜のためのもの。
-user66001


プロセスをチェックするための最良の方法が存在します。stackoverflow.com/questions/3043978/...
トレバー・ボイド・スミス

回答:


166

そのようなことを行う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

@DreadPirateShawnでは、単に0ではなく/ dev / nullを使用する理由を教えてください。番号を使用すると、少なくともnoob(私のような)に対してコードが読みやすくなります。リダイレクトなし、何もありません
Silviu

2
@シルヴィウ?グーグル/dev/null:「/ dev / nullはコマンドの標準出力をnullデバイスにリダイレクトします。nullデバイスは、書き込まれた情報を破棄する特別なデバイスです」...を使用0すると、コマンド出力がというファイルにリダイレクトされ0ます。この場合、より快適になる> /dev/nullことをお勧めします-出力を破棄する標準/適切な方法であるため、どこにでも表示されます。
DreadPirateShawn

申し訳ありませんが、実行前にプログラムが実行されているかどうかを確認する小さなスクリプトにこれを使用しました。(google chromeの実行可能ファイルはrunコマンドと同じ名前を持たないため、少し拡張する必要がありましたが、exec名はchromeのみです。)
Cestarian

3
-xパラメータを追加してpgrep、正確なアプリケーションを探すようにしてください。そうしないと、別のアプリの名前の中に同じ文字列が見つかった場合に誤った修正が行われます。私はそれを見つけるために1時間を費やしました。
サノスアポストロ

1
プログラムが使用することを実行していないかどうかを確認するには! pgrep
モハメドNoureldin

36

のようなものを使用する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をご覧ください。


3
これは技術的には真実ですが、私は実際に実際にそのような問題に遭遇しました。ほとんどのプログラムは、スクリプトを壊すような方法で名前を変更しません。したがって、単純なスクリプトの場合、pgrepまたはのようなものpsは完全に適切であり、あなたのアプローチは過剰に思えます。ただし、公開配布用のスクリプトを作成する場合は、可能な限り安全な方法で作成する必要があります。
スコットセヴェランス

2
@ScottSeveranceプログラムの名前の変更は問題ではありません。関係なく介入が必要です。同じプログラムを実行している他のユーザー、またはスクリプトが突然誤検知を引き起こし、間違った動作をする類似した名前を持つ他のプログラムです。私は、「ほとんどの作品」よりも「作品」を好むだけです。
ガイラ

2
ミスポーク。しかし、私たちの多くはシングルユーザーシステムを実行しています。また、複数ユーザーの状況では、ユーザー名のgrepも簡単です。
スコットセベランス

1
スクリプトが実行中に失敗し、ファイルのロックを解除する前に停止した場合はどうなりますか?
jp093121

2
@ jp093121スクリプトが終了すると、EXITトラップがトリガーされます。スクリプトの終わりに到達したために終了するか、終了コマンドであるか、(処理可能な)シグナルを受信するかにかかわらず、rmコマンドが実行されます。そのため、トラップが設定された後に終了する限り、ロックは解除されます。
ガイラ14

18

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

#!/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


ありがとう!私もこれを試してみました、それも完璧に動作します:)
Nirmik

pgrep同じ15文字の制限「機能」前述している、したがって、例えば、pgrep gnome-power-managerまた失敗する
Thorsenの

1
必ずpgrepの-xオプションを使用してください。「名前(または-fが指定されている場合はコマンドライン)がパターンと完全に一致するプロセスのみに一致します。」
アラステアアーバイン14

5

私は通常pidof -x $(basename $0)、スクリプトが既に実行されているかどうかを確認するためのスクリプトを持っています。


2

@ rommel-cidのアイデアをリフティングpidofして、||で使用できます。(||)プロセスが存在しない場合はコマンドを実行し、プロセスが存在する場合は&&を実行して、if / then / else条件をすばやく作成します。たとえば、実行中のプロセス(プロセス名が「chrome」の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
$

1

確認する必要のあるバイナリがシステム全体にインストールされていないため、「単純な」ソリューションはどれも役に立ちませんでした。したがって、パスを使用して確認する必要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

0

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


0

を使用して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

1
ああ、これはUbuntuのQ&Aサイトであるため、ここでの回答の一部がCentOS 7で機能しないことは驚くことではありません。Linuxの他のバージョンはunix.stackexchange.comで
Geek長老

回答の作成者はCentOSを使用していますが、この回答はUbuntuでも有効です。
フィリップ-Zyan Kリー

0
## 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


-1

2016年9月23日の時点で、muruのスクリプトが機能するためには、pgrepにオプション "-x"が必要と思われます。

#!/bin/bash

if pgrep -x "conky" > /dev/null 2>&1
then
  echo "conky running already"
else
  echo "now starting conky"
  conky
fi
exit 0

Ubuntu 16.04.1マシンで上記のスクリプトを試し、テストしました。楽しい!


-1
#!/bin/bash
while [ true ]; do     # Endless loop.
  pid=`pgrep -x ${1}`  # Get a pid.
  if [ -z $pid ]; then # If there is none,
    ${1} &             # Start Param to background.
  else
    sleep 60           # Else wait.
  fi
done

1
Ask Ubuntuへようこそ!この答えを編集して、これが何をするかについての具体的な詳細を加えて展開することをお勧めします。(AskUbuntuでどのような回答が最も価値があると考えられるについての一般的なアドバイスについては、「良い回答を書くにはどうすればよいですか?」も参照してください。)
David Foerster

-3

isProcessRunning(){if [$(pidof $ 1)> / dev / null]; retval = 'true'; else retval = 'false'; fi; echo $ retval; }

isProcessRunning geany

本当

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.