web-dev-qa-db-ja.com

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

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

90
Highway of Life

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 "httpd"

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

警告!!!

ps axの出力を単純に解析していることを覚えておいてください。これは、Linux出力で見られるように、単にプロセスで一致するのではなく、そのプログラムに渡される引数でも一致することを意味します。このメソッドを使用するときは、できるだけ具体的にすることを強くお勧めします(たとえば、./running "mysql"は 'mysqld'プロセスにも一致します)。可能であれば、whichを使用して完全なパスをチェックすることを強くお勧めします。


参照:

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

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

160
Caleb Gray

PIDを知っている必要があります!

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

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

バックグラウンドで何かを起動するときは常にpidを保存します。 Bashでは、これは$! Bash変数を使用して実行できます。そうすることで、あなたはSO多くの手間を省くことができます。

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

そのため、ここで問題は、pidが実行されているかどうかを知る方法になります。

単に行う:

 ps -o pid = -p <pid> 

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

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

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

24
peterh

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

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

たとえば、私のシステムでは(bashの4つのインスタンスと、remminaの1つのインスタンスが実行されています):

$ pidof bash remmina
6148 6147 6144 5603 21598

他のUnicesでは、pgrepまたはpsgrepの組み合わせは、他の人が正当に指摘したように、同じことを達成します。

14

最も簡単な方法は、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
6
Pawel Solarski

これは、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
6
Johnsyweb

さまざまな提案をまとめると、私が思いつくことができた最もクリーンなバージョン(単語の一部をトリガーする信頼できない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"
5
gletscher

ちょっとした追加:-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,...>オプションを使用して、特定のフィールドを選択して印刷することもできます。

5
Tatjana Heuser

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

3
olibre

プロセスの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

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

1
icarito

答えのどれも私のために働いていなかったので、ここに私のものです:

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

説明:

|tr -d '\n'

これにより、端末によって作成された復帰が削除されます。残りは this postで説明できます。

0
Jeff Luyet

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

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

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

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

これは、ベース名が「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でgwakの代替としてawkを使用してテストしました。

以下に、より用途の広いソリューションと使用例を示します。

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

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

  • 正確なプログラム名(関数の最初の引数)をチェックします。 「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
Raigedas