Share this:

Bash Shell Awesomeness – Mass Killing Processes (On Ubuntu)

I am not a Linux newbie, but neither am I an expert. So, I sometimes tend to come across some really cool stuff and I just have to share.

Here is the story. We use this application at work (I won’t point any fingers :)) which tends to run as a whole lot of processes when it starts up, and these processes don’t all have the same parent process either. Once in a while this application can get into a bad state where you have to manually kill all the processes to restart everything. Now as you might imagine this can be a bit of a pain since there are quite a few processes even if you only count the parents.

Here is where some bash magic comes to the rescue. Luckily for us, this application runs as a separate Linux user so all the processes have the same user id and we’re able to use the following command to kill everything in one fell swoop.

ps -ef | grep ^1002 | cut -c 5-15 | sudo xargs kill

Here is a quick rundown of what it does:

  • the ps command is obvious, we get the processes that are currently active
  • we pipe the output to grep in order to find all the lines that begin with a particular id (this is the id of the user that runs the application)
  • we then pipe the output of that to the cut command to pull out characters 5 to 15 of every line (i.e. the process id will live in that character range)
  • we then pipe the output of that to xargs which lets us use each line of that output as an argument to the kill command, thereby killing all those processes (the sudo bit is really optional and you would use it only if your current user didn’t have permission to kill the processes)

Update: As Sam pointed out in the comments below kill -9 should only ever be used as a last resort as it will create ‘orphaned shared memory segments’ and is therefore best avoided if possible

I don’t know about you, but I thought that was pretty cool :). The only side-effect is that all processes owned by that particular user will get killed (i.e. if you have a shell opened as that user).

I wonder if there is an easier way of doing this with bash? And it would also be great if we didn’t have to kill all processes owned by a user, but rather could mass-kill a bunch of processes based on some other criteria. If anyone is a bash expert, feel free to supply some tips :).

Update: Apparently, according to the comments, there are a number of way of doing this, using either a shorter pipeline or even just one command that would even let you pick particular processes based on criteria (e.g. pkill). Have a look through the comments for details. Thanks to all the commenters for the great feedback!

  • Jeremy

    I guess if I think fast enough, I might be able to guess what that troublesome application is. Is it something I can search on, perhaps?

    • http://www.skorks.com Alan Skorkin

      I do recall it having features that could be called search related :). Deductive force is strong with you :).

  • http://www.matejunkie.com/ Mike Adolphs

    I’d stick to killall rather than piping through 4 different commands. Basically it’s the same as “cat abc|grep xyz” or “grep xyz abc”. Both solutions work just fine, but one solution is nicer.
    However, in the end the only thing that matters is whether it works or not and both ways do.

    • http://www.skorks.com Alan Skorkin

      Thanks for the tip, I’ll definitely have a look at killall. But, yeah like you said, as long as it works. It just blows my mind a little that one can do so much with what amounts to a one-liner.

  • PiX

    Simplicity…..
    $ killall -u user

    • http://www.skorks.com Alan Skorkin

      Ahh, good one. What would be powerful though if you could supply some kind of criteria or even a regex to the command rather than killing all processes belonging to a user. It looks like you can do:

      killall -u user -c procname

      But it doesn’t look like procname can be a regex.

  • anon

    Useless use of grep there… the -u option in ps lets you specify only processes used by some $USERNAME

    ps -fu $USERNAME | awk ‘{print $2}’ | sudo xargs kill -9

    • http://www.skorks.com Alan Skorkin

      Hmmm, awk, thats another great one (why didn’t I think of that :)). Cheers for that.

  • Michael Bubb

    Hello – what about something like:

    for i in `pgrep appname`
    do
    kill $i;
    done

    I use this on occasion with a backup program that spawns a number of related processes and hangs…

    • http://www.skorks.com Alan Skorkin

      That’s great:
      pgrep – sounds like a really handy one to know about

      • http://www.dennogumi.org Luca Beltrame

        I think “pkill” does also pattern matching.

        • http://www.skorks.com Alan Skorkin

          Well, there we go, I just knew linux would have the tools I envisioned.

  • http://alicious.com/ pbhj

    Doesn’t Alt+SysRq+K do the same thing – kills all active user processes. Plus you don’t need to be able to open a console to get it.

    IIRC it’s now disabled by default in some Linux distros (Ubuntu at least) and so you may need to make some config changes to enable is. Try Alt+SysRq+H to get help info.

    • http://www.skorks.com Alan Skorkin

      That is also a great tip and a novel (at least to me) way of looking at the problem. Thanks for sharing.

  • http://blog.adaptivesoftware.biz Parag Shah

    Thanks, I will use this for some scripts.

    • http://www.skorks.com Alan Skorkin

      You’re welcome

  • Jack

    Been using: ps -ef | grep foo | awk “{print $1}” | xargs kill … for systems without killall for years. Not news to me but glad people are finally starting to Feel the Power. Of course, I’ve been a unix/linux admin for going on 16 years now :-)

    • http://www.skorks.com Alan Skorkin

      Yeah, the more I use linux the more I keep finding some really cool stuff that you can do with it :)

  • Øyvind Grønnesby

    pgrep also has the associated pkill, which will send a signal to all matching processes.

    • http://www.skorks.com Alan Skorkin

      Thanks, looks like a very handy one that one and seems to be exactly what I was after, will need to go try it out now.

  • http://chanux.wordpress.com chanux

    ‘ps -u alan’ will filter processes by user ID alan :)
    And you should check this site http://www.commandlinefu.com

    • http://www.skorks.com Alan Skorkin

      That looks like a useful site, cheers for sharing.

  • heretic

    Others have been there, done that (and with more flexibility too boot): http://www.perlmonks.com/?node_id=448715

    • http://www.skorks.com Alan Skorkin

      That looks like a nice perl script, although massive overkill for the problem that I needed to solve.

  • Sam

    Anyone who thinks using “kill -9” as a default is awesome clearly doesn’t understand UNIX or Linux.

    Welcome to orphaned shared memory segment hell. You get to reboot to get that memory back.

    • http://www.skorks.com Alan Skorkin

      Thanks for sharing the info, I wasn’t aware that kill -9 would do that, of source when kill by itself doesn’t work, what choice do you have?

      • Sam

        You have many choices. Read the kill man page and learn about signals. Perhaps your poorly behaving app responds to HUP. -9 is a last resort and you should update this post to reflect that as you’re just spreading bad ideas.

        • http://www.skorks.com Alan Skorkin

          That’s a good idea I will update the post to reflect the fact that -9 is only to be used as a last resort. Cheers for the feedback.

  • http://varrojo.algorithmia.net Alejandro Segovia

    Yet another one; cheers ;)

    kill -9 $(ps u -u $USERNAME | awk ‘{print $2}’)

    • http://www.skorks.com Alan Skorkin

      Hehe, thanks!

  • Ben Beecher

    The xarg is unnecessary. Kill can take a list of processes to kill –

    ps -ef | grep ^1002 | cut -c 5-15 | sudo xargs kill -9

    can become

    kill -9 `ps -ef | grep ^1002 | cut -c 5-15 `

    (Or $(foo) if you prefer)

    • http://www.skorks.com Alan Skorkin

      Ahh, thats a useful shortcut as well, thanks.

  • ericb

    While it is cool, your example has nothing to do with Bash.

  • Matt

    This post is definitely offensive. You should probably clarify the danger of your post.

    If you run almost all of these commands on an application run by root, you will receive undefined results. In this case, undefined results probably means that you will crash your system.

    That said, here is how to do it on less forgiving OSes that do not mandate the use of sudo:

    On a UNIX and most non-Ubuntu Linux systems, this is equivalent:

    kill -9 `ps -ef | grep [username_string] | awk ‘{print $2}’`

    If you’re on Unix and you want to do it by UID (which would be preferable as these are predefined in the passwd file) , you can do this:

    kill -9 `ptree [UID] | awk ‘{print $1}’`

    (linux equivalient is pstree)

    This will kill all children and the parent.

    Run a second ps -ef after the fact to search for possible zombies. If you are using this advice in a script and do not reap the zombie processes, your admin will become agitated.
    Ps -ef does not show all running processes, so the examples given here may miss children of all processes that were found.

    The easy way:

    You will use far less CPU cycles simply killing the shell (or parent process, depending) for the user running the application.

    Example:

    kill -9 [ID of user shell or parent process].

    Kill -9 should not be used on a first attempt as if it attempts to SIGHUP a process that is performing writes or a system-critical process, you will likely corrupt data. Using a simple kill is a safe interrupt level (SIGTERM) to use in a script for killing process – if something is performing a system critical operation, the process will not be killed.

    A request was made for a method to avoid killing the actual shell or parent process in a bash shell. Do the following:

    Linux:

    kill `pstree [parent PID, or UID] | grep -v [parent PID, or UID]`

    this may also work:

    kill `pstree ([parent PID, or UID]) | grep -v $1`

    I honestly can’t remember what shell that works with haha, bourne, maybe? I’ll let you know.

    • http://www.skorks.com Alan Skorkin

      Thanks for the detailed explanation, it is much appreciated. I didn’t intend this post as expert advice on linux shell usage, just something we did at work that I thought was cool. The real benefit is when others come along and expand on the ideas, present better ways and warn of dangers (like you have done and others as well) in the comments. That way everyone gets to learn more.

  • Anon

    We tend to have the same issue with a tomcat4 webapp, I generally use:

    ps aux | grep tomcat4 | awk ‘{print $2}’ | xargs kill -9

    This way you can specify the pid of any processes which you are grepping for, and kill them all without killing all other processes that belong to that user, that is assuming that they all run under a similar process executable.

    • http://www.skorks.com Alan Skorkin

      Yeah that would work as well, but like you said they do all have to have something similar to grep for.

  • Pingback: Destillat KW33-2009 | duetsch.info - GNU/Linux, Open Source, Softwareentwicklung, Selbstmanagement, Vim ...()