can't kill PID from script loop

2019-09-18 01:29发布

I need a function for a script that gets pid for clipit (clipboard manager) and kills clipit. Pretty straightforward stuff I think except for some reason the shell is puking back an error about killing the PID. Here's my function:

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

and here is the terminal error:

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

I've tried removing the sending output to null and that makes no difference. I have two instances of clipit running to ensure both PIDs are detected and killed; however, the PIDs are echoed ok but not being nuked. But if I manually 'kill 24760 24791' the PIDs are killed:

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

Any ideas what I have wrong here I would appreciate reading them.

EDIT

actually if I have only one instance of clipit running then it gets killed using the above onliner fine. 2 clipits or more then it fails to kill any, yet retrieves the PIDs ok.

标签: bash shell
4条回答
虎瘦雄心在
2楼-- · 2019-09-18 02:00

I can't at first look decipher your rather complex egrep, but if you're trying to kill a certain process id, what about:

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

Awk is one of the ancient AT&T Unix commands, but can come in handy when you need to pick a column out of a list.

查看更多
beautiful°
3楼-- · 2019-09-18 02:01

Don't try to reinvent the wheel. If pkill is available use it.

pkill -f clipit

If not you can use something like.

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

查看更多
冷血范
4楼-- · 2019-09-18 02:02

Why cant you just do this in your function? Try it and see if it makes any difference

ps aux | grep clipit | awk '{print $2}' | xargs kill -9 
查看更多
Summer. ? 凉城
5楼-- · 2019-09-18 02:23

This is one of those uncommon cases where you should not quote a parameter expansion.

The issue is that when you have two or more clipits, you end up setting clipitPid to a multiline string. When you then call kill "$clipitPid", the quotes ensure that the entire value of $clipitPid are given to kill as a single argument. Since kill only accepts process or job IDs, and the two-line string "24760\n24791" is not a process or job ID, kill complains.

Had you written kill $clipitPid, then bash would have word-split the value of $clipitPid and provided the separate words as separate arguments to kill, which would have made kill happy.

查看更多
登录 后发表回答