Bashスクリプトでは、次のことを(擬似コードで)行いたいと思います。
if [ a process exists with $PID ]; then
kill $PID
fi
条件文の適切な式は何ですか?
プロセスの存在を確認するには、次を使用します
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
最善の方法は次のとおりです。
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」コマンドの抽象化の精神を壊します。
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
または
if [ -n "$(ps -p $PID -o pid=)" ]
後者の形式では、-o pid=
は、ヘッダーなしでプロセスID列のみを表示する出力形式です。引用符は、空でない文字列演算子-n
が有効な結果を得るために 必要 です。
-p $PID
を指定したps
コマンドでこれを行うことができます。
$ ps -p 3531
PID TTY TIME CMD
3531 ? 00:03:07 emacs
次の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は失敗します。それでは、すべての場合に強制終了を試みて、その戻り値を確認して、それがどのように行われたかを確認してみませんか?
欲しいみたい
wait $PID
$pid
が終了すると戻ります。
それ以外の場合は使用できます
ps -p $PID
プロセスがまだ生きているかどうかを確認します(pidを所有していなくても機能するため、これはkill -0 $pid
よりも効果的です)。
たとえば、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時間ごとにAmazon SQSからの新しいメッセージをチェックしましょう。
#!/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 $?
ここでは、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は存在するが別のアプリケーションで使用されている場合、「予期しない結果」が生じる可能性があります。