这是我的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的进程不存在。它确实回显了终端中的剩余句子。任何线索?
答案 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 -e
与ps -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"