无法从脚本循环中杀死PID

时间:2014-03-23 03:24:31

标签: bash shell

我需要一个脚本函数来获取clipit(剪贴板管理器)的pid并杀死clipit。我认为非常简单的东西,除了某些原因外壳正在回击关于杀死PID的错误。这是我的功能:

stat=0
while [[ "$stat" == 0 ]] ; do
    clipitPid=$(ps aux|egrep -m 1 "[ \t]{1,}[0-9]{1,2}:[0-9]{1,2}[ \t]*clipit$"|sed -r "s/^[^ ]*[ ]*([0-9]{3,5})[ \t]{1,}.*$/\1/") #; echo "\$clipitPid: ${clipitPid}"
    kill "$clipitPid" 0>/dev/null 1>/dev/null 2>/dev/null
    stat="$?"
done

这是终端错误:

10:12 ~ $ stat=0 ; while [[ "$stat" == 0 ]] ; do clipitPid=$(ps aux|egrep "[ \t]{1,}[0-9]{1,2}:[0-9]{1,2}[ \t]*clipit$"|sed -r "s/^[^ ]*[ ]*([0-9]{3,5})[ \t]{1,}.*$/\1/") ; echo "\$clipitPid: ${clipitPid}" ; kill "$clipitPid" 0>/dev/null 1>/dev/null 2>/dev/null ; stat="$?" ; done
$clipitPid: 24760
24791
bash: kill: 24760
24791: arguments must be process or job IDs

我已经尝试将发送输出删除为null,这没有任何区别。 我有两个clipit运行实例,以确保检测到并杀死了两个PID;然而,PID回应良好但没有被破坏。但如果我手动'杀死24760 24791',PID就会被杀死:

10:12 ~ $ kill 24760 24791
10:12 ~ $ ps aux|grep clipit
[3]-  Terminated              clipit
[4]+  Terminated              clipit

任何想法我在这里错了我会很感激阅读它们。

修改

实际上如果我只有一个clipit实例运行,那么使用上面的在线程序就可以杀死它。 2个剪辑或更多,然后它无法杀死任何,但检索PID确定。

4 个答案:

答案 0 :(得分:2)

不要试图重新发明轮子。如果pkill可用,请使用它。

pkill -f clipit

如果没有,你可以使用类似的东西。

kill $(ps -eo pid,comm|grep clipit|grep -v grep|cut -d' ' -f1)

答案 1 :(得分:2)

这是引用参数扩展的不常见情况之一。

问题是,当您有两个或更多个剪辑时,最终会将clipitPid设置为多行字符串。当您再调用kill "$clipitPid"时,引号会确保将$clipitPid的整个值作为单个参数提供给kill。由于kill仅接受进程或作业ID,并且双行字符串“24760 \ n24791”不是进程或作业ID,kill会抱怨。

如果你写了kill $clipitPid,那么bash会对$clipitPid的值进行单词分词,并将单独的单词作为kill的单独参数提供, kill很高兴。

答案 2 :(得分:1)

为什么你不能在你的功能中这样做?试一试,看看它是否有任何区别

ps aux | grep clipit | awk '{print $2}' | xargs kill -9 

答案 3 :(得分:0)

我一开始看起来无法解读你的相当复杂的egrep,但是如果你试图杀死某个进程ID,那么:

kill `ps ax | fgrep clipit | fgrep -v fgrep | awk '{ print $1 }'`

Awk是古老的AT& T Unix命令之一,但是当您需要从列表中选择一列时,它可以派上用场。