219

How do I kill the last spawned background task in Linux?

Example:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
flybywire
  • 261,858
  • 191
  • 397
  • 503
  • 20
    How can this be not programming related? Bash programming is not programming? – flybywire Oct 26 '09 at 13:14
  • 7
    This is in the overlap region between SO and SU, but I think it fits better here on SO. My criteria for thinking this way is that if @flybywire is doing this in a script, it's programming. If he just wanted to do it from the command line I'd say it belongs on SU. – Bill the Lizard Oct 26 '09 at 19:58
  • 12
    Shell scripting is programming too. – cletus Oct 28 '09 at 01:12

8 Answers8

315

You can kill by job number. When you put a task in the background you'll see something like:

$ ./script &
[1] 35341

That [1] is the job number and can be referenced like:

$ kill %1
$ kill %%  # Most recent background job

To see a list of job numbers use the jobs command. More from man bash:

There are a number of ways to refer to a job in the shell. The character % introduces a job name. Job number n may be referred to as %n. A job may also be referred to using a prefix of the name used to start it, or using a substring that appears in its command line. For example, %ce refers to a stopped ce job. If a prefix matches more than one job, bash reports an error. Using %?ce, on the other hand, refers to any job containing the string ce in its command line. If the substring matches more than one job, bash reports an error. The symbols %% and %+ refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using %-. In output pertaining to jobs (e.g., the output of the jobs command), the current job is always flagged with a +, and the previous job with a -. A single % (with no accompanying job specification) also refers to the current job.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 1
    For the record, I think this only works if job control is enabled. Although I think you can turn it on in scripts (`set -m`), it's intended for interactive use. See http://stackoverflow.com/questions/690266/why-cant-i-use-job-control-in-a-bash-script as well – falstro Nov 18 '13 at 10:23
  • 11
    Very useful symbols, these `%1` and `%%` - especially. Some things don't die on Ctrl-C, so you need to Ctrl-Z them, and then `kill -9 %%`. One example where I found it useful is: `while true; do mplayer ; date >> restarts.log; done` - Ctrl-C will just get you to next loop iteration. Before I had to do `ps` or maybe `jobs -l`, and then re-type the PID, which is tedious. – Tomasz Gandor Mar 04 '14 at 14:27
  • Is there one for all jobs? – CMCDragonkai Apr 17 '14 at 04:50
  • 3
    @TomaszGandor That's why you might want to replace `while true` with `while sleep 1`. This will give you a short delay before restarts if you can live with that, and if you hit ctrl-c twice, the second one will interrupt the sleep, ending it with a non-zero exit and breaking out of the loop. – falstro May 31 '14 at 19:49
  • If there is confusion about which user it belongs to, the result may be "`kill: failed to parse argument: '%1'`" (e.g., for `sudo kill %1` after Ctrl + Z in, for example, `sudo less /media/someUser/364c375a-523c-41ae-b858-0fa9774540a3/grub/grub.cfg`). `kill %1` (without `sudo`) may give the desired outcome, but with an error message: "`bash: kill: (23076) - Operation not permitted.` and `[1]+ Stopped sudo less /media/someUser/364c375a-523c-41ae-b858-0fa9774540a3/grub/grub.cfg`" – Peter Mortensen Mar 11 '23 at 10:49
252

There's a special variable for this in Bash:

kill $!

$! expands to the PID of the last process executed in the background.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
falstro
  • 34,597
  • 9
  • 72
  • 86
  • 71
    @polm23; no, `^Z` doesn't background jobs, it stops them. A subsequent `bg` does the actual 'backgrounding' (resumes execution in the background), and after that `$!` works as expected. – falstro Oct 16 '12 at 14:39
  • Assuming the `????` stands for one or more commands to be executed after the kill, if any of those commands relies on work done by the background process, be mindful of any cleanup or finishing-up tasks which the background process might perform in a signal handler after receiving a (trappable) signal. Best to add a `wait` (followed perhaps by a `sync` or even a `sleep `) right before the first of any such 'dependent' commands. – ack Jan 30 '16 at 03:02
  • 2
    For completion: As a single % also refers to the current job you can kill the stopped job (^z) with "kill %". I use this almost always after ^z. – t3o Mar 13 '19 at 09:41
  • This only works if you have job-control enabled, which is only on by default in interactive shells (though since you're referring to using ctrl-z I guess you're also referring to using an interactive shell) - but this has been outlined in other answers here, not sure why this is "for completeness" :) – falstro Mar 13 '19 at 09:44
51

The following command gives you a list of all background processes in your session, along with the pid. You can then use it to kill the process.

jobs -l

Example usage:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139
Dave Vogt
  • 18,600
  • 7
  • 42
  • 54
31

This should kill all background processes:

jobs -p | xargs kill -9
royhowie
  • 11,075
  • 14
  • 50
  • 67
Prabhu Are
  • 463
  • 2
  • 7
  • 15
  • 1
    This is what I'd use before, but `kill -9 %%` is less typing :) – Tomasz Gandor Mar 04 '14 at 14:29
  • 4
    @TomaszGandor That will kill only the current job i.e. last job stopped in foreground or started in background. The command in the answer will kill ALL jobs. – Alex Bitek May 02 '14 at 10:52
  • 5
    [do not kill -9](http://unix.stackexchange.com/questions/8916/when-should-i-not-kill-9-a-process) – Lesmana Feb 22 '15 at 18:32
2
skill doB

skill is a version of the kill command that lets you select one or multiple processes based on a given criteria.

royhowie
  • 11,075
  • 14
  • 50
  • 67
gte525u
  • 4,594
  • 2
  • 16
  • 8
0

You need its pid... use "ps -A" to find it.

jldupont
  • 93,734
  • 56
  • 203
  • 318
0

As in John Kugelman's answer, % is related to job specification.

How can we efficiently find that? Use less's &pattern command. It seems man uses the less pager (I am not that sure). In 'man' Bash, type &%, and then type Enter. It will only show lines that containing '%'. To reshow all, type &. And then Enter.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
qeatzy
  • 1,363
  • 14
  • 21
-4

Just use the killall command:

killall taskname

for more info and more advanced options, type "man killall".

zakk
  • 375
  • 1
  • 4
  • 14
  • 4
    I think killall is a bit aggressive when you actually have easy access to the PID. And dangerous, too, especially if you're root – Dave Vogt Oct 26 '09 at 13:20
  • 3
    Not very helpful, if you had to `killall python` or `killall java`, while having something useful running elswhere in the system. – Tomasz Gandor May 02 '14 at 13:15