プロセスID(PID)が存在するかどうかを確認する方法


184

bashスクリプトで、以下を(疑似コードで)実行したいと思います。

if [ a process exists with $PID ]; then

    kill $PID 

fi

条件ステートメントの適切な式は何ですか?

回答:


182

プロセスの存在を確認するには、次を使用します

kill -0 $pid

しかし、@ unwindが言ったように、とにかくそれを殺すつもりなら、

kill $pid

または、競合状態になります。

のテキスト出力を無視killして、終了コードに基づいて何かを実行したい場合は、

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi

1
manページを見ると、kill -0は「終了コードはシグナルが送信されるかどうかを示します」です。それで、これは実際にプロセスを殺すのですか、それともそれが殺せるかどうかをあなたに話しますか?
リチャードH

24
kill必ずしもプロセスを強制終了するとは限らないという点で、多少誤解されています。プロセスにシグナルを送るだけです。 シグナル15、SIGTERMをプロセスに送信kill $PIDすると同等kill -15 $PIDです。これは終了の指示です。シグナル0はありません。これは、シグナルをkillプロセスに送信できるかどうかを確認するだけの特別な値です。これは、ほとんどの場合、シグナルが存在するかどうかを確認することとほぼ同じです。linux.die.net/man/2/killlinux.die.net/man/7/signalを
ChristofferHammarströmJun

43
これには、プロセスが実行中のユーザーによって所有されていない場合、kill -0を呼び出す権限がない可能性があるという問題があります。ps -p $ PID> / dev / null 2>&1を使用することをお勧めします。これにより、シグナルを送信する権限がない場合でも、プロセスのステータスを確認できます。
mckoss

6
@mckoss:その場合、彼はとにかくそれを殺すことはできません。
ChristofferHammarström12年

2
したがって、私は推測します-を使用するkill -0には、実際にはこれを行う必要があります:kill -0 25667 ; echo $?-そして、0返された場合、そのPIDを持つプロセスを強制終了できます。プロセスPID(言う)が存在しない場合には、$?あろう1障害を示します。あれは正しいですか?
sdaau 2013年

264

最善の方法は:

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

の問題:

kill -0 $PID

pidが実行中であり、それを強制終了する権限がない場合でも、終了コードはゼロ以外になります。例えば:

kill -0 1

そして

kill -0 $non-running-pid

通常のユーザーには区別できない(ゼロ以外の)終了コードがありますが、initプロセス(PID 1)は確実に実行されています。

討論

テストの本体が「殺害」である場合、殺害と競合状態を説明する答えは正確です。一般的な「bashでPIDの存在をどのようにテストするか」を探しに来ました。

/ procメソッドは興味深いですが、ある意味では、「ps」コマンドの抽象化の精神を壊します。つまり、Linusが「exe」ファイルを別の名前で呼び出すことにした場合は、/ procを調べる必要はありません。


1
ps -pは常に私に0のステータスを返します
IttayD

1
ps -p ####はUbuntu 14.04でうまく動作しました。
Ligemer、2016

3
ps -pは、実行中のどのプロセスとも一致しない場合、空のプロセスリストを出力するため、常にos xでステータスコード0を返します
Douglas Correa

macOS Sierraでこれが動作することを確認できます。また、-p少なくともその場合、は不要です。ps $PIDまったく同じ結果になります。
user137369 2017

移植性は/ procの使用を避けるための良い理由ですが、LinuxがそのABIを壊すことは、私が特に心配するシナリオではありません。
David Roundy

67
if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

または

if [ -n "$(ps -p $PID -o pid=)" ]

後者の形式で-o pid=は、ヘッダーのないプロセスID列のみを表示する出力形式です。空でない文字列演算子が有効な結果を得るには、引用符が必要-nです。


1
2番目の方法は、Macでも機能します(Mac OS Xには/ proc FSがありません)。ただし、サブシェルを使用して回避し、MacとLinuxの両方でこれを使用することができます:if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ウィル

残念ながら、psオプションや機能はプラットフォームによって異なる傾向があるため、完全に移植可能ではありません。
Tripleee

1
$PIDが空の場合[ -e /proc/$PID ]/proc/ディレクトリがまだ存在するため、trueを返します。
マグネ

34

psコマンドで-p $PIDこれを行うことができます:

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs

11

次の2つの方法があります。

私のラップトップで特定のアプリケーションを探すことから始めましょう:

[root@pinky:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

すべての例で、PID 3358が検索されます。

最初の方法:「ps aux」を実行し、2列目のPIDに対してgrepを実行します。この例では、firefoxを探し、次にPIDを探します。

[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358

したがって、コードは次のようになります。

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

2番目の方法/proc/$PIDディレクトリで何かを探すだけです。この例では「exe」を使用していますが、他の何でも使用できます。

[root@pinky:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

したがって、コードは次のようになります。

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

ところで:何が悪いのkill -9 $PID || true


編集:

数か月間それについて考えた後..(約24 ...)ここで私が与えた最初のアイデアは素晴らしいハックですが、非常に移植性がありません。Linuxの実装の詳細をいくつか教えていますが、Mac、Solaris、* BSDでは機能しません。将来のLinuxカーネルでは失敗するかもしれません。他の応答で説明されているように、「ps」を使用してください。


少なくともkill -9の部分は間違っているようです(サブプロセスはkillしていません)
ヌレッティン14

最初の方法を使用すると、なぜ[:missing `] 'が表示されるのですか?
テンマイル2015

1
/proc/$PID/exe通常のファイルではありません。したがって、[ -f /proc/$PID/exe ]常にfalse結果を返します。お試しください[ -h /proc/$PID/exe ]
Alexander Yancharuk、

8

あなたがしたいようです

wait $PID

$pid終了すると戻ります。

それ以外の場合は使用できます

ps -p $PID

プロセスがまだ生きているかどうかを確認します(これはkill -0 $pid、pidを所有していなくても機能するためよりも効果的です)。


1
プロセスは、現在のシェルの子でなければなりませんか、それが与えるよう待機はそれほど効果的ではありません:pid 123 is not a child of this shell
Calumah

7

私はそれが悪い解決策だと思います。それは競争状態を切り開きます。テストと殺害の呼びかけの間にプロセスが停止した場合はどうなりますか?その後、殺害は失敗します。では、すべてのケースでkillを試してみて、戻り値をチェックして、それがどのように行われたかを調べてみませんか?


残念ながら、kill(1)の終了コード+1は、さまざまなエラー状況を区別しません(シグナルを送信できなかったプロセスごとに、終了値が1ずつ増加するように見えます)。OPが独自のkill(2)ラッパーを作成することを気にしない場合、kill(2)呼び出しが失敗した後、ERRNOの値に基づいて異なる値で終了する可能性があります。
ちょうど誰か

現時点では、チェックなしでkill -9を実行しているだけです。存在しない場合は、「プロセスが存在しない」というエラーが表示されます。何が起こったかをどのようにテストしますか?
Richard H

14
うっかりしないでkill -9。それは即座にプロセスを強制終了し、それ自体をクリーンアップする機会を与えません。代わりにkillwhichと同等のものを使用してくださいkill -15。それがうまくいかない場合は、その理由を調べる必要がありますkill -9。これは最後の手段としてのみ使用してください。
ChristofferHammarström10年

0

ここで、PIDを.pid(/ run / ...のようなもの)と呼ばれるファイルに保存し、まだ実行されていない場合にのみスクリプトを実行します。

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

注: pidの呼び出し方法をチェックしないため、競合状態があります。システムが再起動され、.pidが存在するが別のア​​プリケーションで使用されている場合、これは「予期しない結果」を引き起こす可能性があります。


0

たとえば、GNU / Linuxでは次を使用できます。

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

または何かのような

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

アプリの名前が表示され、IDのない名前だけが表示されます。


1
pidof負のPIDは意味をなさないので負の数を返さず、を殺すことはできないinitため、条件は意味がありません(さらに>、リダイレクトを実行しないようにするにはエスケープする必要があります)。空の結果をチェックしたいのですが、もちろん、適切なツールと同様にpidof、終了コードを設定してそれが機能したかどうかを通知します。したがって、適切な解決策は、if Pid=$(pidof 'process_name'); then ...または(Pid後で値を必要としない場合)単純にif pidof 'process_name'; then...
トリプリー2016

@tripleeeは正解です。このpidof例には、bashのtest仕組みに関する誤解がたくさんあります。gnu.org/software/bash/manual/html_node/...
ブルーノBronosky

0

以下のコードは、プロセスが実行されているかどうかをチェックし、実行されている場合は何もしません。

プロセスが実行されていない場合にのみ、Amazon SQSからの新しいメッセージを1時間ごとにチェックしてみましょう。

#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
    /usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
    echo "do nothing, just smile =)"
fi
exit $?
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.