1

これが私のシェルスクリプトです:

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep| awk '{print $1}')
kill -s SIGINT $PIDS
echo "Done sendings signal"

コマンドライン引数としてプロセスの名前を渡しています。
ターゲットプロセスは実際に SIGINT シグナルを受信して​​終了していますが、echo コマンドは実行されません。

助言がありますか?

更新:
コードを次のように変更しました。

#!/bin/bash
PIDS=$(ps -e |grep $1 | grep -v grep | awk '{print $1}'|grep -v $$)
echo $PIDS
kill -s SIGINT $PIDS
echo "Done sendings signal"
echo "The current process is $$"

ここで、奇妙なことに気付きました
。スクリプトは機能していますが、期待どおりではありません。スクリプトの外側のコマンド ラインで次のコマンド
ps -e|grep process-name|grep -v grep|awk '{print $1}'|grep -v $$
を実行すると、プロセス名の pid が得られますが、シェル スクリプト内で同じコマンドを実行すると、それを変数 PIDS に割り当ててから PIDS をエコーすると、プロセスの pid に加えてもう 1 つの pid が表示されます。名前。したがって、kill コマンドを実行すると、2 番目の pid を持つプロセスが存在しないというエラーが発生します。端末の残りの文をエコーし​​ます。どんな手掛かり ?

4

3 に答える 3

1

実際には、いくつかの可能性しかありません。コマンドラインからこれを実行していると仮定すると、メッセージ表示されます...もちろん、実行していることがシェルプロセスのPIDをPIDSに入れていない限り、その場合、killは(sub )エコーをヒットする前にコマンドを実行するシェル。

提案:killを呼び出す前に$ PIDSをエコーし​​て、そこに何があるかを確認してください。実際、何が起こるかを確認するために、killをコメントアウトして、コマンドを試してみたくなります。

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep| awk '{print $1}')
echo $PIDS
# kill -s SIGINT $PIDS
echo "Done sendings signal"

もちろん、いつでもスクリプトを実行してbash -xすべてを確認できます。

于 2012-07-07T14:40:37.000 に答える
0

スクリプトは機能します。エコーが実行されていないことがわかる唯一の理由は、$ 1の値とスクリプトファイル名が組み合わされて、スクリプトPIDも収集され、スクリプトが自殺することです。

PIDS行は、ps、grep、別のgrepを実行しているプロセスを生成します。したがって、PIDSには、grepを実行しているプロセスはありませんが、親プロセス自体はどうでしょうか。

試す:

#!/bin/bash
PIDS=$(ps -e | grep $1 |grep -v grep | awk '{print $1}' | grep -v "^$$\$" )
kill -s SIGINT $PIDS
echo "Done sendings signal"

または、適切な安全グリップを使用してパイプを次々に実行します。

編集:「$1」の選択が多すぎることは明らかです。したがって、スクリプトを次のように書き直します。

#!/bin/bash
# Gather the output of "ps -e". This will also gather the PIDs of this
# process and of ps process and its subshell.
PSS=$( ps -e )
# Extract PIDs, excluding this one PID and excluding a process called "ps".
# Don't need to expunge 'grep' since no grep was running when getting PSS.
PIDS=$( echo "$PSS" | grep -v "\<ps\>" | grep "$1" | awk '{print $1}' | grep -v "^$$\$" )
if [ -n "$PIDS" ]; then
    kill -s SIGINT $PIDS
else
    echo "No process found matching $1"
fi
echo "Done sending signal."
于 2012-07-07T14:41:07.800 に答える
0

ps -eすべてのプロセスと同一でps -Aあり、すべてのプロセスを選択します(http://linux.die.net/man/1/psを参照)。つまり、ps -e「端末を制御していないプロセスを含む、他のユーザーのプロセスに関する情報」を表示します(MacOSXのマニュアルページps)。$$これは、Charlie Martinがすでに指摘しているように、シェルプロセスのPID()も強制終了することを意味します。これはps -e、次のようなコマンドの出力行もgrepするためです。

67988 ttys000 0:00.00 /bin/bash ./killpids sleep

の出力をps -eファイルに記録するだけで、スクリプトが自殺したことを確認できます。

./killpids sleep 2>err.log

#!/bin/bash
# cat killpids

echo $$

for n in {1..10}; do
   sleep 5000 &
done

sleep 1

unset PIDS
PIDS="$(ps -e | tee /dev/stderr | grep "$1" | grep -v grep | awk '{print $1}')"
#PIDS="$(ps -www -U $USER -o pid,uid,comm | tee /dev/stderr | grep "$1" | grep -v grep | awk '{print $1}')"

wc -l <<<"$PIDS"

#kill -s SIGINT $PIDS
echo kill -s TERM $PIDS
kill -s TERM $PIDS

echo "Done sendings signal"
于 2013-03-12T11:46:12.860 に答える