回答:
プロセスの存在を確認するには、次を使用します
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
kill
必ずしもプロセスを強制終了するとは限らないという点で、多少誤解されています。プロセスにシグナルを送るだけです。 シグナル15、SIGTERMをプロセスに送信kill $PID
すると同等kill -15 $PID
です。これは終了の指示です。シグナル0はありません。これは、シグナルをkill
プロセスに送信できるかどうかを確認するだけの特別な値です。これは、ほとんどの場合、シグナルが存在するかどうかを確認することとほぼ同じです。linux.die.net/man/2/killとlinux.die.net/man/7/signalを
kill -0
には、実際にはこれを行う必要があります:kill -0 25667 ; echo $?
-そして、0
返された場合、そのPIDを持つプロセスを強制終了できます。プロセスPID(言う)が存在しない場合には、$?
あろう1
障害を示します。あれは正しいですか?
最善の方法は:
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を調べる必要はありません。
-p
少なくともその場合、は不要です。ps $PID
まったく同じ結果になります。
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
または
if [ -n "$(ps -p $PID -o pid=)" ]
後者の形式で-o pid=
は、ヘッダーのないプロセスID列のみを表示する出力形式です。空でない文字列演算子が有効な結果を得るには、引用符が必要-n
です。
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
オプションや機能はプラットフォームによって異なる傾向があるため、完全に移植可能ではありません。
$PID
が空の場合[ -e /proc/$PID ]
、/proc/
ディレクトリがまだ存在するため、trueを返します。
次の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」を使用してください。
/proc/$PID/exe
通常のファイルではありません。したがって、[ -f /proc/$PID/exe ]
常にfalse
結果を返します。お試しください[ -h /proc/$PID/exe ]
。
私はそれが悪い解決策だと思います。それは競争状態を切り開きます。テストと殺害の呼びかけの間にプロセスが停止した場合はどうなりますか?その後、殺害は失敗します。では、すべてのケースでkillを試してみて、戻り値をチェックして、それがどのように行われたかを調べてみませんか?
kill -9
。それは即座にプロセスを強制終了し、それ自体をクリーンアップする機会を与えません。代わりにkill
whichと同等のものを使用してくださいkill -15
。それがうまくいかない場合は、その理由を調べる必要がありますkill -9
。これは最後の手段としてのみ使用してください。
ここで、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が存在するが別のアプリケーションで使用されている場合、これは「予期しない結果」を引き起こす可能性があります。
たとえば、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のない名前だけが表示されます。
pidof
負のPIDは意味をなさないので負の数を返さず、を殺すことはできないinit
ため、条件は意味がありません(さらに>
、リダイレクトを実行しないようにするにはエスケープする必要があります)。空の結果をチェックしたいのですが、もちろん、適切なツールと同様にpidof
、終了コードを設定してそれが機能したかどうかを通知します。したがって、適切な解決策は、if Pid=$(pidof 'process_name'); then ...
または(Pid
後で値を必要としない場合)単純にif pidof 'process_name'; then...
以下のコードは、プロセスが実行されているかどうかをチェックし、実行されている場合は何もしません。
プロセスが実行されていない場合にのみ、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 $?