Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a few Stopped background processes.

kill $(jobs -p) and kill `jobs -p` have no effect

kill %1, kill %2, etc. successfully terminate individual processes

How can I kill every background process with one command?

Also, why do the first two commands not work for me?

I'm running Linux Mint 15, 64 bit

share|improve this question

4 Answers 4

up vote 8 down vote accepted

When they're running

Seems like you can just do this with kill and the output of jobs -p.

Example

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Now I have 3 fake jobs running.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Kill them all like so:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Confirming they're all gone.

$ jobs
$

When they're stopped

If you have jobs that are stopped, not running you do this instead.

Example

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK so that didn't kill them, but that's because the kill signal cannot be handled by the process itself, it's stopped. So tell the OS to do the killing instead. That's what a -9 is for.

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

That's better.

$ jobs
$ 

When some are running and some are stopped

If you have a mixed bag of processes where some are stopped and some are running you can do a kill first followed by a kill -9.

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Extending the time slightly if you need more to allow for processes to stop themselves first.

Signals

Neither a HUP (-1) or a SIGTERM (-15) to kill will succeed. But why? That's because these signals are kinder in the sense that they're telling the application to terminate itself. But since the application is in a stopped state it can't process these signals. So you're only course is to use a SIGKILL (-9).

You can see all the signals that kill provides with kill -l.

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

If you want to learn even more about the various signals I highly encourage one to take a look at the signals man page,man 7 signal.

share|improve this answer
    
why do we have + symbol for the first process and - symbol for the second process and no symbol in the third? –  Ramesh Apr 12 at 19:46
    
I got the same results as you. However I want to terminate instead of kill, since I've read that is safer. I tried kill -15 $(jobs -p), but that had no effect. I guessed that stopped processes can only be killed, but then again kill %number does terminate (individual) stopped processes. –  user49888 Apr 12 at 19:49
    
@Ramesh The + and - are just the last processes that I touched when I was setting up the examples. The + means that any commands that do not explicitly include a %# will act on that command. The dash (-) is the 2nd to last command I touched. –  slm Apr 12 at 19:50
    
@user49888 - the kill -9 .. should've worked. what are the processes? Are they defunct or orphaned processes? –  slm Apr 12 at 19:51
    
Corrected my comment. I meant that I tried kill -15 .., which had no effect. Are there any adverse effects of kill versus terminate? –  user49888 Apr 12 at 20:00

You can try this.

for x in `jobs -p`; do kill -9 $x; done

However, if you want to terminate the process, you can issue the command as,

for x in `jobs -p`; do kill -15 $x; done

From the Wiki page of Kill command,

A process can be sent a SIGTERM signal in four ways (the process ID is '1234' in this case):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

The process can be sent a SIGKILL signal in three ways:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

As explained in this answer, this is the difference between terminate and kill.

The terminate signal, SIGTERM, is a signal that can be intercepted in a program. Often processes which are meant to run in the background will catch this signal and start a shutdown process, resulting in a clean exit. The kill signal, SIGKILL, cannot be intercepted. When this is sent to a process it will result in an abrupt termination of that program.

When you shutdown or reboot your computer for example, usually a SIGTERM is sent to the running processes first allowing them to exit in a clean way if they support it. Then, after a few seconds a SIGKILL is sent to the processes which are still running so that resources in use are forcibly released (e.g. files in use) and the shutdown sequence can continue (e.g. unmounting filesystems).

share|improve this answer
    
This does kill every background process. However, is there any way to terminate them instead, since I believe that is safer? –  user49888 Apr 12 at 19:31
    
If you want to terminate, you can use -15 in the kill command. –  Ramesh Apr 12 at 19:34
    
-15 will not work here either. See my A. –  slm Apr 12 at 19:56
    
@Ramesh - the last 2 paragraphs aren't right. A SIGTERM is not sent (not initially). Processes are attempted to stop first via there service stop/start scripts. If that was the case that a 9 was sent to the process then with the processes stopped as in the OP's example the kill -9 in my example wouldn't have worked. –  slm Apr 12 at 20:00
    
@slm, thanks for the clarification :) –  Ramesh Apr 12 at 20:17

Ok, playing around with this I see that when you kill a job which is stopped (where executing has been paused but not terminated), then it won't finish until it is brought into the foreground. Programs are commonly stopped by pressing Ctrl-Z on the terminal. Most terminals send the SIGSTOP in this case, but of course there are also other ways of sending it such as with kill -STOP or kill -19.

It is normal behaviour for the program not to finish right away since the program has to be running to process the default SIGTERM signal sent by kill. Moreover, sometimes after bash sends SIGTERM to a background process, it somehow ends up stopped (although the SIGTERM is still pending).

The safest way to get all the jobs to finish (without resorting to kill -9) is first to send SIGTERM with a normal kill, then to send SIGCONT to any remaining jobs, eg:

kill $(jobs -p)
kill -18 $(jobs -p)

The SIGCONT (18 is the signal number) will bring any stopped jobs into the foreground so that they can process the SIGTERM as they normally would.

If all the programs don't finish with this, then there are a few other signals you can try that normally make the process finish, before resorting to kill -9. The first one I recommend is SIGHUP since a lot of programs that usually block the other termination signals respond to SIGHUP. This is usually sent when a controlling terminal closes, in particular it is sent when a ssh session with a tty finishes. Many interactive programs, such as shells, won't respond to other termination signals but will to this since it would be a problem for them to stay running after an ssh session finishes (or after any controlling terminal closes). To try this you can so

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Again of course you need to make sure the program isn't stopped so that it can process the signal. Other termination signals you can try are SIGINT (kill -2) and SIGQUIT (kill -3). But of course the benefits of trying the full range diminish and may lead to a inevitable SIGKILL (aka kill -9).

share|improve this answer
    
If you do a man signal you can get the reference material to back this up. –  slm Apr 12 at 20:05
    
This is a softer form of what my A suggests. There are instances where I've run into in the past where this still will not clean things up fully so if you're doing this from a script the kill -9 .. method will work in most cases. This will sometimes leave processes hanging around, so will fail more of the time. It's a trade off you have to decide. Better to be heavy handed and kill everything, risking data/cleanup vs. having a softer cleanup, but having to do more analysis as your kills get progressively more harsh. –  slm Apr 12 at 20:13
    
@slm, you should avoid kill -9 whenever possible as this just pulls the plug without giving the program a chance to properly clean up. I will update with some alternatives. –  Graeme Apr 12 at 20:17
    
As I said your flavor is softer then what I suggested, it comes down to what you're trying to do vs. willing to tolerate from a risk perspective. I've used your method as well as mine. They're both correct IMO. Also a kill ..; sleep <time>; kill -18 ..; sleep <time>; kill -9 .... Basically working up to the -9`. –  slm Apr 12 at 20:23
    
@slm, the kill -18 is definitely something that should be used since it is common to have stopped jobs (and in some cases it appears that bash somehow stops running jobs before sending SIGTERM). As added above SIGHUP is also worth trying since many programs that don't respond to the others will respond to this (try it with a shell). Beyond that though, yes, it is not so worthwhile as the SIGKILL is probably inevitable. –  Graeme Apr 12 at 20:39

This will terminate all jobs in your current shell one by one:

while kill %; do :; done

Explanation: % refers to last job in the list, so it will loop until kill returns non-zero value, which would mean that there is no more jobs to terminate.

Another approach could be first sending SIGTERM, then SIGCONT so your jobs can continue and first thing they'll do is receive your SIGTERM.

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(for some reason built-in kill is weird, so I used external one here).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.