我正在编写一个脚本来杀死同一进程的所有实例。由于它将在Linux,AIX,HP-UX和Solaris上使用,我只需要使用内置的bash(sh)函数。这就是killall
,pkill
等不适合我的原因。
只有一个进程的实例,它应该以传统方式被杀死:
kill -TERM `ps -ef | grep -v grep | grep $process | awk '{print $2}'`
然而,有时程序会运行额外的实例,这就是ps -ef | …
返回多个PID的原因。需要报告。
示例:
bash-3.2$ ps -ef | grep -v grep | grep perl | awk '{print $2}'
5267
5268
5269
5270
5271
我的想法是将这些值存储在临时变量中,然后在for循环中向每个值发送kill信号。
bash-3.2$ tmp=`ps -ef | grep -v grep | grep perl | awk '{print $2}'`
bash-3.2$ echo $tmp
5267 5268 5269 5270 5271
但是,如果发生这种情况,我仍然需要这些信息(存在多少个实例)。
看来我需要检查存储在tmp
变量中的整个字符串,并且可能计算空格?
无论如何,问题减少了如何检查$tmp
变量存储的值的数量?
答案 0 :(得分:3)
要获得最大portability和可靠性,请使用-A
(POSIX同义词-e
)和自定义格式-o
而不是-f
。
您对ps
输出的过滤很脆弱:它可能与其他进程匹配。您必须排除grep进程,并且您可能还需要排除脚本,并且可能还有其他完全无辜的进程(例如您的脚本本身)被捕获,因为它们的命令行恰好包含{{1作为子字符串。尽可能严格地过滤。使用$process
,您只得到两列(PID和没有参数的命令),没有标题。
您不需要使用循环来执行查杀,ps -o pid= -o comm=
接受多个参数。对于计数,让shell执行:你有一个以空格分隔的数字列表,让shell执行单词拆分(引号外有kill
)并计算结果单词的数量({{1} })。
$(…)
如果您的shell在所有计算机上都是bash或ksh,则可以使用数组。
$#
答案 1 :(得分:2)
使用xargs:
ps aux | grep -ie perl | awk '{print $2}' | xargs kill -9
答案 2 :(得分:1)
你可以使用一个在两种情况下都适用的循环:
for pid in $(ps -ef | grep -v grep | grep $process | awk '{print $2}'); do
echo $pid
done
或计算比赛次数:
if [ $(ps -ef | grep -v grep | grep $process | awk '{print $2}' | wc -l) -gt 1 ]
then
# more than one
fi