特定のプロセスが実行されているかどうかを判断する、プラットフォームに依存しない(Linux/Unix | OSX)Shell/bashコマンドが必要です。例えばmysqld
、httpd
...これを行う最も簡単な方法/コマンドは何ですか?
pidof
とpgrep
は、何が実行されているかを判断するための優れたツールですが、残念ながら、一部のオペレーティングシステムでは使用できません。明確なフェールセーフは、次を使用することです。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
を使用して完全なパスをチェックすることを強くお勧めします。
参照:
プロセス引数(pgrep "mysqld"
など)で何らかのパターン認識を試みることでプロセスを見つけることは、遅かれ早かれ失敗する運命にある戦略です。 2つのmysqldを実行している場合はどうなりますか?そのアプローチを忘れてください。あなたはそれを一時的に正しくするかもしれません、そして、それは1年か2年の間働くかもしれませんが、それからあなたが考えなかった何かが起こります。
プロセスID(pid)のみが真に一意です。
バックグラウンドで何かを起動するときは常にpidを保存します。 Bashでは、これは$!
Bash変数を使用して実行できます。そうすることで、あなたはSO多くの手間を省くことができます。
そのため、ここで問題は、pidが実行されているかどうかを知る方法になります。
単に行う:
ps -o pid = -p <pid>
これはPOSIXであり、したがって移植可能です。プロセスが実行されている場合はpid自体を返し、プロセスが実行されていない場合は何も返しません。厳密に言えば、コマンドはpid
という単一の列を返しますが、空のタイトルヘッダー(等号の直前のもの)を指定したため、これが要求された唯一の列であるため、psコマンドはヘッダーをまったく使用しません。解析が容易になるため、これが必要です。
これはLinux、BSD、Solarisなどで動作します。
別の戦略は、上記のps
コマンドからの終了値でテストすることです。プロセスが実行されている場合はゼロ、実行されていない場合はゼロ以外である必要があります。 POSIX仕様では、エラーが発生した場合、ps
は0を超えて終了する必要がありますが、「エラー」を構成するものは不明です。したがって、私は個人的にはこの戦略を使用していませんが、すべてのUnix/Linuxプラットフォームで同様に機能することは確かです。
ほとんどのLinuxディストリビューションでは、 pidof
(8)を使用できます。
指定したプロセスの実行中のすべてのインスタンスのプロセスIDを出力します。実行中のインスタンスがない場合は何も出力しません。
たとえば、私のシステムでは(bash
の4つのインスタンスと、remmina
の1つのインスタンスが実行されています):
$ pidof bash remmina
6148 6147 6144 5603 21598
他のUnicesでは、pgrep
またはps
とgrep
の組み合わせは、他の人が正当に指摘したように、同じことを達成します。
最も簡単な方法は、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
これは、Unix、BSD、Linuxのほとんどのフレーバーで動作するはずです。
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
テスト済み:
PATH=...
]さまざまな提案をまとめると、私が思いつくことができた最もクリーンなバージョン(単語の一部をトリガーする信頼できない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"
ちょっとした追加:-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,...>
オプションを使用して、特定のフィールドを選択して印刷することもできます。
pgrep -l httpd
を使用していますが、どのプラットフォームにも存在するかどうかはわかりません...
OSXで確認できるのは誰ですか?
起動すると、その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
の answer に基づきます。特定のPIDが実行されているかどうかを知るための秘trickは、ps -o pid= -p $PID
命令にあります。
答えのどれも私のために働いていなかったので、ここに私のものです:
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で説明できます。
このアプローチは、コマンド「ps」、「pidof」、およびrestが使用できない場合に使用できます。私は個人的にツール/スクリプト/プログラムでprocfsを頻繁に使用しています。
egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3
何が起こっているのか少し説明:
これは、ベース名が「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"
これが私のバージョンです。特徴:
スクリプト:
#!/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