在shell脚本中执行kill命令后没有执行任何命令

时间:2012-07-07 14:32:35

标签: shell signals kill

这是我的shell脚本:

#!/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,但是当我在shell脚本中执行相同的命令时,将其分配给变量PIDS然后回显PIDS,然后它除了显示进程名称的pid之外还显示另外一个pid。因此,当kill命令执行时,它会给出一个错误,即第二个pid的进程不存在。它确实回显了终端中的剩余句子。任何线索?

3 个答案:

答案 0 :(得分:1)

真的只有几种可能性。假设你只是从命令行运行它,你应该看到消息...当然,除非你正在做什么把你的shell进程的PID放在PIDS中,在这种情况下kill命中之前会杀死运行命令的(子)shell。

建议:在调用kill之前回显$ PIDS并查看其中的内容。事实上,我很想评论杀戮并尝试命令,只是为了看看会发生什么。

#!/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运行脚本来查看所有内容。

答案 1 :(得分:0)

你的脚本有效。我可以看到没有执行echo的唯一原因是$ 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."

答案 2 :(得分:0)

ps -eps -A相同,并选择所有流程(参见http://linux.die.net/man/1/ps),i。即ps -e显示“有关其他用户进程的信息,包括那些没有控制终端的进程”(ps的Mac OS X手册页)。这意味着您还将杀死shell进程的PID($$),正如Charlie Martin已经指出的那样,因为您还将查看ps -e命令的输出行,如下所示:

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"