6

I started an application that won’t run, yet I can’t delete it cause it’s still running. I can print the PID, but not kill the process using it.

~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process
aweeeezy
  • 221

2 Answers2

17

Did you notice that you got two different PIDs in the two tries?

Consider this: if you type a command like vi raven.txt, then ps ax will display a line that shows a command of vi raven.txt.  Likewise, if you type a command like grep snappr, then ps ax will display a line that shows a command of grep snappr.  And, if you pipe the output of that ps through grep snappr, the grep will find the line that is describing itself.  So, if you type

$ ps ax | grep snappr | awk '{print $1}'

repeatedly, it will print a different number every time (because it's printing the PID of grep, and you get a new, unique grep process every time you run the command).

Finally, consider: the kill command cannot be executed until its argument(s) are known.  For its argument to be known, the $(ps ax | grep snappr | awk '{print $1}') pipeline must have completed.  This implies that the grep must have terminated1.  Therefore, the kill is being given the PID of the grep process, but only after the grep process has terminated -- so, naturally, it reports "No such process".

Perhaps I should have mentioned that there is no snappr process running.  If there were, your first command would output two numbers: the PID of snappr, and the PID of grep snappr.  Now, if snappr were running, your command might start running semi-correctly, by which I mean it does what you want but also gives an error message.  If the snappr is running with PID 42097, and grep snappr runs with PID 70848, then the kill command will be kill 42097 70858, which will kill the snappr and get an error message from trying to kill the grep process that no longer exists.

You'll probably want to improve on this.  My favorite way, which I invented 20 years ago, it to change the grep to grep "[s]nappr", which will match snappr but will not match itself.  Another approach is to use pgrep rather than ps | grep.


1 Alternatively, the awk could finish if the grep merely closed its stdout.  This would be very unusual behavior for a *nix program.

8

Shorter Answer

Don’t jump through Bash hoops to kill snappr with ps, piped through grep and then piped through awk like that. Instead try to kill it like this using pkill; no muss or fuss and it targets based on process name out of the box:

sudo pkill snappr

Longer Answer

Not too clear with how Snapper operates on a system process level, but the issue could be that you are only grabbing the child process ID instead of the parent process ID.

In fact I believe the method you are using to grab a process ID (ps ax | grep snappr | awk '{print $1}') would return a whole list of process IDs connected to snappr regardless of whether it is parent or child. So using that you might kill one process ID that is just a child process ID yet the parent ID would still be active and able to “spawn” another child process to compensate.

So perhaps you can do something like this to grab the definitive parent ID of whatever process ID you feed it and act on it; simple proof of concept of how it works:

ps -p [process ID] -o ppid=

Running that bare command in Bash will give you the parent process ID of the child process ID you put in [process ID]. So if the child ID 4567 has a parent process ID of 123 then the command would be:

ps -p 4567 -o ppid=

And that would return, 123.

That said, this could be a dangerous way of dealing with a stray process since if your script grabs the actual parent process ID of snapper, then the parent of that process ID could really be your own Bash shell. So you might inadvertently just kill your Bash shell instead of the snapper knocking you off the system while leaving snapper process running.

But all that said, why not make your life easier and just run pkill like this:

sudo pkill snappr

That will kill all processes connected to snappr without any fancy command line juggling.

Giacomo1968
  • 58,727