プロセスが実行されているかどうかを判断するLinux / Unixコマンド?


97

特定のプロセスが実行されているかどうかを判断する、プラットフォームに依存しない(Linux / Unix | OSX)シェル/ bashコマンドが必要です。例mysqldhttpd...これを行う最も簡単な方法/コマンドは何ですか?

回答:


168

一方でpidofpgrep動いているものを決定するための優れたツールです、彼らは、残念ながら、両方のいくつかのオペレーティングシステムでは使用できません。確実なフェイルセーフは、次のものを使用することです。ps cax | grep command

Gentoo Linuxでの出力:

14484?S 0:00 apache2
14667?S 0:00 apache2
19620?SL 0:00 apache2
21132?SS 0:04 apache2

OS Xでの出力:

42582 ?? Z 0:00.00(smbclient)
46529 ?? Z 0:00.00(smbclient)
46539 ?? Z 0:00.00(smbclient)
46547 ?? Z 0:00.00(smbclient)
46586 ?? Z 0:00.00(smbclient)
46594 ?? Z 0:00.00(smbclient)

LinuxとOS Xの両方で、grepは終了コードを返すため、プロセスが見つかったかどうかを簡単に確認できます。

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

さらに、PIDのリストが必要な場合は、それらも簡単にgrepできます。

ps cax | grep httpd | grep -o '^ [] * [0-9] *'

LinuxとOS Xで出力が同じ場合:

3519 3521 3523 3524

次の出力は空の文字列で、実行されていないプロセスに対してこのアプローチを安全にします。

エコー ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'

このアプローチは、単純な空の文字列テストを記述し、検出されたPIDを繰り返し処理する場合にも適しています。

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

実行権限(chmod + x running)でファイル(「running」という名前のファイル)に保存し、パラメーターを指定して実行することで、テストできます。 ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

警告!!!

ps axLinuxの出力に見られるように、単に出力を解析しているだけであり、プロセスで単に一致しているのではなく、そのプログラムに渡された引数でもあることに注意してください。この方法を使用するときは、できるだけ具体的にすることを強くお勧めします(たとえば、./running "mysql"「mysqld」プロセスにも一致します)。which可能な場合はを使用してフルパスをチェックすることを強くお勧めします。


参照:

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm


プロセスは実行できますが、停止しました。したがって、mysqldまたはhttpdが「稼働中」(応答)かどうかをテストすることが目的である場合は、それが停止しているかどうかも確認する必要があります。
oluc 2013年

2
申し訳ありませんが、答えは確かにセマンティックの観点からは正しいですが、プロセス引数ベクトルのパターンマッチングによってプロセスを見つけようとすることにはまったく反対です。そのようなアプローチは遅かれ早かれ失敗する運命にあります(実際には、さらにチェックが必要であると言って、自分でそれを認めます)。別の回答に自分の推奨事項を追加しました。
peterh 2013年

6
grepまた、例えば(実行すると自分自身を見つけるでしょうps cax | grep randomname常に0ので返しますgrep発見がgrep randomname。()...これは明らかであると思います一つの修正は例えば、プロセス名の最初の文字の周りに角括弧を追加することですps cax | grep [r]andomname
カイルG.

ps cax | rev | cut -f1 -d' ' | rev解析を簡単にするために、名前列のみが表示されます。
Tyzoid

1
ps caxコマンド名が完全に出力されない場合があります。たとえば、「chrome-browser」の代わりに「chrome-browse」を出力します。
jarno

24

あなたはPIDを知っているべきです!

プロセスの引数に対して何らかのパターン認識(のようなpgrep "mysqld")を試みてプロセスを見つけることは、遅かれ早かれ失敗する運命にある戦略です。2つのmysqldを実行している場合はどうなりますか?そのアプローチを忘れてください。あなたはそれを一時的に正しくするかもしれません、そして、それは1年か2年の間働くかもしれませんが、それからあなたが考えていなかった何かが起こります。

プロセスID(pid)のみが本当に一意です。

バックグラウンドで何かを起動するときは常にpidを保存します。Bashでは、これは$!Bash変数を使用して行うことができます。そうすることであなたは自分自身をとても多くの面倒から救うでしょう。

プロセスが実行されているかどうかを確認する方法(pidによる)

したがって、問題は、pidが実行されているかどうかを知る方法になります。

単に行います:

ps -o pid = -p <pid>

これはPOSIXであり、移植性があります。プロセスが実行されている場合はpid自体を返し、プロセスが実行されていない場合は何も返しません。厳密に言うと、コマンドは単一の列を返しますpidが、空のタイトルヘッダー(等号の直前にあるもの)が指定されており、これが要求される唯一の列であるため、psコマンドはヘッダーをまったく使用しません。解析が容易になるため、これが必要です。

これはLinux、BSD、Solarisなどで動作します。

別の戦略は、上記のpsコマンドの終了値でテストすることです。プロセスが実行中の場合はゼロでなければならず、実行されていない場合はゼロ以外でなければなりません。POSIX仕様ではps、エラーが発生した場合に> 0で終了する必要があると記載されていますが、「エラー」の原因は不明です。したがって、私は個人的にその戦略を使用していませんが、すべてのUnix / Linuxプラットフォームで同様に機能することを確信しています。


1
ただし、サービスが実行されているかどうかを判断するという質問には答えません。このような場合、PIDは不明になるため、この回答は、PID わかっている場合にのみ有効です。
Highway of Life

2
違う。私のコメントの全体的な要点は、少し前に戻ってgrep <sometext>、特定のプロセスを見つけるために何らかの形で行う必要がある状況に最初に気づいた場合、プロセスを開始したときに何か間違ったことをした、ということです。私はそれが実際にプロセスの開始方法を彼がコントロールしているというOPの質問からそれを取ります。
peterh 2013年

2
OP質問のより正確な「用語」は、「サービスが実行されているかどうかを判別するためのクロスプラットフォームコマンド」である必要があります。これは、チェックを実行している同じシステムではなく、外部システムであるため、PIDは単にまったく知られています。
Highway of Life

2
これは絶対に簡単なことではありません。関心のあるプロセスは、システムがPIDが循環するのに十分な時間が経過した後に停止した可能性があり、別のプロセスに、チェックしている同じPIDが割り当てられた可能性があります。 stackoverflow.com/questions/11323410/linux-pid-recycling
クレイメーション

1
@claymation。フェアポイント。ただし、PIDの衝突は、同じサービスの2つのインスタンスを誤って開始するというよりもはるかに可能性が低いため、PIDメソッドはプロセス引数のパターンマッチングよりも優れています。ちょうど私の2セント。:-)
peterh

15

ほとんどのLinuxディストリビューションでは、pidof(8)を使用できます。

指定されたプロセスの実行中のすべてのインスタンスのプロセスIDを出力するか、実行中のインスタンスがない場合は何も出力しません。

たとえば、私のシステムでは(4つのインスタンスbashと1つのremminarunning インスタンスがあります):

$ pidof bash remmina
6148 6147 6144 5603 21598

他のUnix上で、pgrepまたは組み合わせpsgrep他の人が合法的に指摘したように、同じことを実現します。


+1 pidof httpdはRed Hat 5では正常に動作しますが、私のRed Hat 4ではpidof存在しません:-(
olibre

確かに、このコマンドは私が思っていたよりも広く普及していません。私はこれをより明確にするために私の回答を編集しました。
フレデリックハミディ

確かにすてきな答え。(サポートされているシステム)。ありがとうございました。
Mtl Dev 2017

7

これは、Unix、BSD、およびLinuxのほとんどのフレーバーで機能するはずです。

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

テスト済み:

  • SunOS 5.10 [したがってPATH=...]
  • Linux 2.6.32(CentOS)
  • Linux 3.0.0(Ubuntu)
  • ダーウィン11.2.0
  • FreeBSD 9.0-STABLE
  • Red Hat Enterprise Linux ESリリース4
  • Red Hat Enterprise Linux Serverリリース5

2
+1はい、単純psです。二避けるためにgrep:私は示唆ps aux | grep [h]ttpd
olibre

ここでは、変数をメインに簡単に入れるために角かっこを使用しませんでしたgrep
Johnsyweb

1
よし;)私はRed Hat AS 4とRed Hat AP 5でテストしたところです。したがって、リストに追加できます:Red Hat Enterprise Linux ESリリース4およびRed Hat Enterprise Linuxサーバーリリース5。乾杯
olibre

@Downvoter:なぜですか?私は何を取りこぼしたか?私の知る限り、受け入れられた答えは同じ検索を行っています!
Johnsyweb

6

最も簡単な方法は、psとgrepを使用することです。

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

コマンドにコマンド引数がある場合は、「grep $ command」の後に「grep cmd_arg1」を追加して、不要な他の可能なプロセスを除外することもできます。

例:引数が指定されたJavaプロセスがあるかどうかを表示します。

-Djava.util.logging.config.file = logging.properties

が走っています

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l

2
実際、を使用ps caxすると、を使用する必要がなくなりますgrep -v。たとえば、次のように使用できますps cax | grep java > /dev/null || echo "Java not running"
Highway of Life

1
3行目に誤りがあります。「running」を「$ running」に変更してください。
プログラマー

5

ほんの小さな追加:-cフラグをpsに追加した場合、grep -v後でgrepプロセスを含む行を削除する必要はありません。すなわち

ps acux | grep cron

bsd-ishシステム(MacOSXを含む)で必要なすべての入力です。 -u。少ない情報が必要な場合はてます。

ネイティブpsコマンドの遺伝学がSysVを指すシステムでは、次を使用します。

ps -e |grep cron

または

ps -el |grep cron 

pidとプロセス名だけではないリストの場合。もちろん、-o <field,field,...>オプションを使用して印刷する特定のフィールドを選択することもできます。


この回答はどのように移植可能ですか?(psコマンドのさまざまな形式をさまざまなプラットフォームで使用する必要があると言います)
peterh

残念ながらpsは、祖先に応じて同じ結果に対して異なるオプションセットを持つツールの1つです。そのため、これについて独自の(他の何にも互換性のない)ラッパーを記述しない限り、先に進むには、遺産の主要な系統を知り、それに応じて適応する必要があります。スクリプトを作成する場合とは異なります。これらの違いを使用して、現在のブランチを判別し、スクリプトの動作を調整します。結論:両方を知る必要があります。有名な例:ラリー・ウォールの「構成」スクリプト。有名な引用:おめでとう、あなたはEuniceを実行していません。
Tatjana Heuser

5

さまざまな提案をまとめると、(単語の一部をトリガーする信頼できないgrepなしで)思いついた最もクリーンなバージョンは次のとおりです。

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0はプロセスを強制終了しませんが、プロセスが存在するかどうかを確認してからtrueを返します。システムにpidofがない場合は、プロセスの起動時にpidを保存します。

$ mysql &
$ echo $! > pid_stored

その後、スクリプトで:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

3

使用してpgrep -l httpdいますが、どのプラットフォームにも存在します...
OSXで確認できるのは誰ですか?


@Johnsywebに感謝します。確認してpidofもらえますか?わかりました。ありがとうございました。したがって、OSXで動作している他のものが見つかるはずです...基本ps|grepは単一のソリューションかもしれません;-)
olibre

1

プロセスのPIDを知っている必要があります。

起動すると、そのPIDが$!変数に記録されます。このPIDをファイルに保存します。

次に、このPIDが実行中のプロセスに対応しているかどうかを確認する必要があります。完全なスケルトンスクリプトは次のとおりです。

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

答えに基づいていますpeterh。特定のPIDが実行されているかどうかを知るための秘訣は、ps -o pid= -p $PID命令にあります。


0

このアプローチは、コマンド 'ps'、 'pidof'およびrestが使用できない場合に使用できます。私は自分のツール/スクリプト/プログラムでprocfsを非常に頻繁に使用しています。

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3

何が起こっているのか少し説明:

  1. -m1-最初の一致でプロセスを停止
  2. "mysqld $ | httpd $"-grepは、mysqldまたはhttpdで終了した行に一致します
  3. / proc / [0-9] *-bashは任意の数字で始まる行に一致します
  4. カット-出力を区切り文字「/」で分割し、フィールド3を抽出します

0

これは、ベース名が「chromium-browser」であるプロセスの数を出力します。

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

これが「0」を出力する場合、プロセスは実行されていません。コマンドは、プロセスパスに改行スペースが含まれていないことを前提としています。サスペンドされたプロセスまたはゾンビプロセスでこれをテストしていません。

Linux gwakawk代替として使用してテストされています。

次に、いくつかの使用例を持つ、より用途の広いソリューションを示します。

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"

0

これが私のバージョンです。特徴:

  • 正確なプログラム名をチェックします(関数の最初の引数)。「mysql」の検索は、実行中の「mysqld」と一致しません
  • プログラム引数(関数の2番目の引数)を検索します

脚本:

#!/bin/bash

# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof $1); do
        cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi

0

答えはどれもうまくいきませんでした。

process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

説明:

|tr -d '\n'

これにより、ターミナルによって作成されたキャリッジリターンが削除されます。残りはこの投稿で説明できます。


-1

次のシェル関数は、POSIX標準のコマンドとオプションのみに基づいているため、ほとんどの(存在しない場合でも)Unixおよびlinuxシステムで動作します。:

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

疑わしい "0]"コマンド名が渡されるとチョークし、名前にスペースが埋め込まれているプロセスの識別にも失敗することに注意してください。

また、最も支持され受け入れられているソリューションpsは、移植性のないオプションを必要とし、その人気にもかかわらず、すべてのUnix / Linuxマシンに存在することが保証されていないシェルを不必要に使用していることにも注意してください(bash


$ isPidRunning 0]たとえば、「0」が実行されている3 [ksoftirqd / 0] 8 [rcuop / 0] 17 [rcuos / 0] 26 [rcuob / 0] 34 [migration / 0] 35 [watchdog / 0] "がここに表示されます。
jarno 2015年

あなたはそのPATHのことを何のために必要ですか?
jarno 2015年

ここでさらにソリューションを開発しました
jarno 2015年

@jarno PATH設定は、スクリプトを移植可能にするための要件です。それ以外の場合、少なくともSolaris 10以前のバージョン、およびおそらく他のUnix実装では失敗します。
jlliagre 2015年

1
@jarno私はそれを行うかもしれませんが、awkに対してもこのPATH設定を繰り返す必要があります。以前のbacktick構文に戻ったため、POSIXより前の構文シェルで移植できることに注意してください。
jlliagre 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.