It's an old question and there are already few good answers, but, I'll try to present mine in a little different way.
Actually, backgrounded processes are called jobs, and job control is very well explained in those 3 short pages: https://www.gnu.org/software/bash/manual/html_node/Job-Control.html
Basically, we can reference a job by a jobspec, that is the symbol %
follow either by another symbol (or a sequence in some fancier cases), or by a job ID. And it's the same for kill
, fg
, bg
or disown
.
%+
(or just %
, or %%
) will reference the latest backgrounded
job (current)
%-
will reference the previous one
%{jobid}
will reference the specified job
To list your backgrounded jobs, you use the command jobs
.
Note
kill $!
has a different behavior, it will kill the latest process sent in the background as a job, and not the latest job created.
e.g
You have sent 5 jobs in the background.
You bring back job #2 in the foreground (fg %2
, or just %2
), then sent it back in the background (<Ctrl-Z>
, then bg
).
It is the latest process sent to the background, but it remains job #2.
So that kill $!
will terminate job #2 - the latest process (re)sent to the background, while kill %+
will kill job #5, the latest job that have been created ("current job"):
$ jobs
[1] Running sleep 1000 &
[2] Running sleep 2000 &
[3] Running sleep 3000 &
[4]- Running sleep 4000 &
[5]+ Running sleep 5000 &
$ fg %2
sleep 2000
^Z
[2]+ Stopped sleep 2000
$ bg
[2]+ sleep 2000 &
$ jobs
[1] Running sleep 1000 &
[2] Running sleep 2000 &
[3] Running sleep 3000 &
[4]- Running sleep 4000 &
[5]+ Running sleep 5000 &
$ kill %+
$ jobs
[1] Running sleep 1000 &
[2] Running sleep 2000 &
[3] Running sleep 3000 &
[4]- Running sleep 4000 &
[5]+ Terminated sleep 5000
$ kill $!
[2] Terminated sleep 2000
$ jobs
[1] Running sleep 1000 &
[3]- Running sleep 3000 &
[4]+ Running sleep 4000 &
jobs
has nooutput
andfg
sais:-bash: fg: 1: no such job
. But typingfg
works well and alsopkill wget
works well. butps -eaf|grep wget
and thenkill <process number>
dose not stop the job. ps: I use the third number as process number. – Mohammad Etemaddar Dec 12 '13 at 07:32ps
. The 3rd # is the parent's process id. – slm Dec 12 '13 at 07:34No such process
and then when I check the process number again usingps -eaf|grep wget
I find that the process number has changed. – Mohammad Etemaddar Dec 12 '13 at 07:36ps
. It sounds like you have a script running multiple wget's or something is restarting wget's after it's killed.. – slm Dec 12 '13 at 07:44ps -eaf|grep wget
gives thegrep wget
process.ps -efa|grep <my user id>
gives this. – Mohammad Etemaddar Dec 12 '13 at 07:50ps -eaef| grep [w]get
. – slm Dec 12 '13 at 07:54pgrep
instead,pgrep wget
. – slm Dec 12 '13 at 07:56eaef
? – Mohammad Etemaddar Dec 12 '13 at 07:58ps -eaf | grep [w]get
. The options are are in theps
man page.man ps
. – slm Dec 12 '13 at 08:01Ctrl-C
afterfg
(method 5 did not work.). Method 4 seems to be the fastest and the shortest to type. – John_West Jan 19 '16 at 21:22fg %1
to bring the job back into foreground. – Jack Chi Jul 18 '18 at 23:44fg 1
notation works as well. Try it. – slm Jul 18 '18 at 23:53kill %%
kills the last background process. Repeating it will kill the one before and so on.kill %1
kills the first background process. – Ronny Sherer Feb 05 '20 at 12:06grep
into not showing the actualgrep
command in the output. Thegrep
command shows up asgrep [w]get
but the commandgrep
is looking for the stringwget
. The[...]
is a set of characters, in this case a set of 1 character,w
. – slm Mar 03 '22 at 05:10kill $(jobs -p)
– Amado Saladino Oct 11 '22 at 20:43