222

bashスクリプトで、次のことを(擬似コードで)実行したいと思います。

if [ a process exists with $PID ]; then

    kill $PID 

fi

条件文の適切な式は何ですか?

4

11 に答える 11

312

最良の方法は次のとおりです。

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は、プロセスが実行中であり、プロセスを強制終了する権限がない場合でも、終了コードがゼロ以外になることです。例えば:

kill -0 $known_running_pid

kill -0 $non_running_pid

通常のユーザーには区別できないゼロ以外の終了コードがありますが、そのうちの1つは仮定による実行であり、もう1つは実行されていません。


部分的に関連し、AnrDaemonによって提供される追加情報:initプロセス(PID 1)は確かにすべてのLinuxマシンで実行されていますが、すべてのPOSIXシステムがLinuxであるとは限りません。PID1がそこに存在することは保証されていません。

kill -0 1 
-bash: kill: (1) - No such process … 

討論

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

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

于 2013-04-02T21:29:31.177 に答える
205

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

kill -0 $pid

しかし、@ unwindが言ったように、いずれにせよ終了させたい場合は、

kill $pid

そうしないと、最初のの後にプロセスが消えた可能性がある競合状態になりますkill -0

のテキスト出力を無視しkillて、終了コードに基づいて何かを実行したい場合は、次のことができます。

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi
于 2010-06-15T09:40:23.260 に答える
78

Linuxなどのprocfsインターフェースを実装するシステムでは、/proc/$PID存在するかどうかを確認できます。

if test -d /proc/"$PID"/; then
    echo "process exists"
fi

それ以外の場合は、psプログラムを使用できます。

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

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

于 2014-06-24T13:23:25.767 に答える
40

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

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs
于 2010-06-15T09:40:20.453 に答える
12

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

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

[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」を使用してください。

于 2010-06-15T09:40:26.033 に答える
8

あなたが望むようです

wait $PID

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

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

ps -p $PID

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

于 2014-05-19T09:00:41.400 に答える
7

これは悪い解決策だと思います。それは競合状態につながる可能性があります。テストと殺害の呼びかけの間にプロセスが終了した場合はどうなりますか?その後、キルは失敗します。では、すべての場合にkillを試して、その戻り値をチェックして、それがどのように行われたかを調べてみませんか?

于 2010-06-15T09:32:48.247 に答える
1

たとえば、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なしの名前だけが表示されます。

于 2014-10-16T09:39:10.783 に答える
1

pid

pgrep [pid] >/dev/null

名前で:

pgrep -u [user] -x [name] >/dev/null

-x」は「完全一致」を意味します。

于 2021-02-19T06:28:50.320 に答える
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が存在するが、別のアプリケーションで使用されている場合、これは「予期しない結果」を引き起こす可能性があります。

于 2015-12-04T15:41:40.233 に答える
-1

はここで@FDSの答えから学び、賛成しました。なぜなら、それは良くて正しいからです。しかし、これが私が読みやすく理解しやすいと思うフォームです:

pid=1234
ps --pid "$pid" > /dev/null
if [ "$?" -eq 0 ]; then
    echo "PID $pid exists and is running."
fi

更新:shellcheck check_if_pid_exists.sh冗長性を回避するために(@FDSが示すように)実際には別の方法で実行する必要があることを教えてくれます:

pid=1234
if ps --pid "$pid" > /dev/null; then
    echo "PID $pid exists and is running."
fi

だから...多分私は将来そのようにすることに適応するでしょう。

とにかく、ここに完全な実行可能なプログラムがあります(これが私の貢献だと思います):

check_if_pid_exists.sh:

#!/usr/bin/env bash

pid=1234

if [ "$#" -gt 0 ]; then
    # At least 1 argument was passed in, so assume it is the PID
    pid="$1"
fi

# Try to print the process (`ps`) information for this PID. Send it to
# /dev/null, however, so we don't actually have to look at it. We just want
# the return code, `$?`, which will be 0 if the process exists and some other
# number if not.
ps --pid "$pid" > /dev/null
if [ "$?" -eq 0 ]; then
    echo "PID $pid exists and is running."
else
    echo "PID $pid does NOT exist."
fi

実行呼び出しと出力のサンプル:

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 28876
PID 28876 exists and is running.

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh
PID 1234 does NOT exist.

eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 5678
PID 5678 does NOT exist.
于 2022-02-15T22:49:36.547 に答える