335

I have started a wget on remote machine in background using &. Suddenly it stops downloading. I want to terminate its process, then re-run the command. How can I terminate it?

I haven't closed its shell window. But as you know it doesn't stop using Ctrl+C and Ctrl+Z.

peterh
  • 9,731

12 Answers12

427

There are many ways to go about this.

Method #1 - ps

You can use the ps command to find the process ID for this process and then use the PID to kill the process.

Example

$ ps -eaf | grep [w]get 
saml      1713  1709  0 Dec10 pts/0    00:00:00 wget ...

$ kill 1713

Method #2 - pgrep

You can also find the process ID using pgrep.

Example

$ pgrep wget
1234

$ kill 1234

Method #3 - pkill

If you're sure it's the only wget you've run you can use the command pkill to kill the job by name.

Example

$ pkill wget

Method #4 - jobs

If you're in the same shell from where you ran the job that's now backgrounded. You can check if it's running still using the jobs command, and also kill it by its job number.

Example

My fake job, sleep.

$ sleep 100 &
[1] 4542

Find it's job number. NOTE: the number 4542 is the process ID.

$ jobs
[1]+  Running                 sleep 100 &

$ kill %1
[1]+  Terminated              sleep 100

Method #5 - fg

You can bring a backgrounded job back to the foreground using the fg command.

Example

Fake job, sleep.

$ sleep 100 &
[1] 4650

Get the job's number.

$ jobs
[1]+  Running                 sleep 100 &

Bring job #1 back to the foreground, and then use Ctrl+C.

$ fg 1
sleep 100
^C
$
slm
  • 369,824
  • The jobs has no output and fg sais: -bash: fg: 1: no such job. But typing fg works well and also pkill wget works well. but ps -eaf|grep wget and then kill <process number> dose not stop the job. ps: I use the third number as process number. – Mohammad Etemaddar Dec 12 '13 at 07:32
  • 1
    @MohammadEtemaddar - use the 2nd number from the output of ps. The 3rd # is the parent's process id. – slm Dec 12 '13 at 07:34
  • When I use the second number, It sais: No such process and then when I check the process number again using ps -eaf|grep wget I find that the process number has changed. – Mohammad Etemaddar Dec 12 '13 at 07:36
  • @MohammadEtemaddar - I'd need to see the output from ps. 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:44
  • The command ps -eaf|grep wget gives the grep wget process. ps -efa|grep <my user id> gives this. – Mohammad Etemaddar Dec 12 '13 at 07:50
  • 3
    @MohammadEtemaddar - ah, the ps is finding the grep. Do it like this: ps -eaef| grep [w]get. – slm Dec 12 '13 at 07:54
  • 1
    @MohammadEtemaddar - you can also use pgrep instead, pgrep wget. – slm Dec 12 '13 at 07:56
  • Would you please tell a little about the functionality of option eaef? – Mohammad Etemaddar Dec 12 '13 at 07:58
  • 3
    @MohammadEtemaddar - sorry the extra e is a typo. Should read ps -eaf | grep [w]get. The options are are in the ps man page. man ps. – slm Dec 12 '13 at 08:01
  • Suddenly, on RHEL5 my job was not killed by Ctrl-C after fg (method 5 did not work.). Method 4 seems to be the fastest and the shortest to type. – John_West Jan 19 '16 at 21:22
  • It's fg %1 to bring the job back into foreground. – Jack Chi Jul 18 '18 at 23:44
  • @JackChi - the fg 1 notation works as well. Try it. – slm Jul 18 '18 at 23:53
  • I did the first, second and third steps, it didnt work, so I just closed the current open tag where I opened the programs, and problem solved – Marcelo Sep 04 '18 at 13:08
  • 6
    kill %% 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:06
  • 1
    what does [ ] do in grep [w]get? – avm Mar 01 '22 at 12:44
  • 2
    @avm - it basically tricks grep into not showing the actual grep command in the output. The grep command shows up as grep [w]get but the command grep is looking for the string wget. The [...] is a set of characters, in this case a set of 1 character, w. – slm Mar 03 '22 at 05:10
  • But if you launched this process yourself, you should already have the pid of this background process. – Sandburg Jun 15 '22 at 12:25
  • you can also kill all background jobs kill $(jobs -p) – Amado Saladino Oct 11 '22 at 20:43
134

In bash you can use fg to get the job to the foreground and then use Ctrl+C

Or list the process in the background with jobs and then do

kill %1

(with 1 replaced by the number jobs gave you)

Zelda
  • 6,262
  • 1
  • 23
  • 28
  • 1
    This sleeps the job. Not remove it... kill -9 %6 is the correct command that will remove the job number 6. Number 9 indicates type of the signal that kill command sends. – 71GA Dec 22 '22 at 10:58
  • Also useful: to kill multiple jobs by their specific numbers, can do kill %{1,2,3,4} (should work in bash/zsh). – avivr Aug 28 '23 at 10:25
36

You can equally use kill $! to kill the most recently backgrounded job.

stanlyof
  • 471
7

EDIT: Once in the foreground, you can Ctrl+C, or as @Zelda mentions, kill with the '%x' where 'x' is the job number will send the default signal (most likely SIGTERM in the case of Linux).

just type fg to bring it to the foreground, if it was the last process you backgrounded (with '&').

If it was not the last one, type: jobs and find the 'job number', represented in '[]'. Then just type:

fg 2

..where '2' is the job number, for example:

foo@bar:~/junk/books$ jobs
[1]+  Running                 okular how_to_cook_a_turkey.pdf &
foo@bar:~/junk/books$ fg 1
okular how_to_cook_a_turkey.pdf            <- this is now in the foreground.
Anthon
  • 79,293
7

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 &
cedbeu
  • 622
6

One thing I don't see here, which I've found very useful especially when testing out commands, is pidof. You can use pidof [command] to find the process id of a process that is currently running. I like it because it allows me to quickly find the id of the command I want, which is usually something I just invoked.

Once you have the pid, you can simply kill the process. It allows for creating simple scripts for killing a process only if it's currently running.

Try431
  • 547
  • 6
  • 15
  • 1
    Ah this helped me! kill %1 wasn't working for some reason, "kill: failed to parse argument: '%1'" and Ctrl+C wasn't working; couldn't find process in ps or anything because it was root (I forgot I used sudo with it) – mejdev Mar 23 '17 at 15:47
6

in bash last stopped process (Ctrl-Z) you will kill by:

kill %%
kill -9 %%

or if want to choose, use:

jobs

then:

kill %N

like kill %2

4

The correct way is to type jobs then use the job number to kill it. In order to use the pid to kill it you need to bring it to the foreground as noted in the first answer.

Try this

~/Desktop$ sleep 1000 &
[1] 7056

~/Desktop$ jobs

[1]+  Running  sleep 1000 &

/Desktop$ kill %1  #(%1 is the job number)

If you run jobs right after you kill it you should see this

Desktop$ jobs
[1]+  Terminated              sleep 1000
drs
  • 5,453
tmac
  • 49
2

The Easiest way is to use -9 flag on kill command

user@host:/path> jobs
[1]+  Running                 /usr/home/script1.sh $i &
user@host:/path> fg
/usr/home/script1.sh $i
^C
[1]+  Stopped                 /usr/home/script1.sh $i
user@host:/path> kill -9 %1
[1]+  Stopped                 /usr/home/script1.sh $i
user@host:/path>
[1]+  Killed                  /usr/home/script1.sh $i
user@host:/path>
user@host:/path> jobs
user@host:/path>
Paulo Tomé
  • 3,782
1

A common example is the stress tool. Let say you ran the following:

$ stress -c 4 -m 4 

and closed the terminal window. The process would continue eating your resources from the background.

Hers’s what I do:

$ x=`pgrep stress` ; sudo kill -9 $x 

pgrep lists the PIDs of the subjected process and stores it into variable x which then used by kill -9 to terminate it.

slm
  • 369,824
0

List All Jobs by typing

jobs

Output>>[1]+ Stopped sudo nano ls.txt

Take this process to foreground and kill

fg %1
then press ctrl+c
  • 3
    This adds nothing to the currently-accepted answer, and moreover won't work in this case. Using kill %1 (as suggested by others) will, but Ctrl+C is meaningless against programs that ignore the keyboard interrupt as mentioned in this question – Fox Mar 19 '21 at 07:38
0

I am lazy and I got bit tired googling what incantation of ctrl % signal number fg bg jobs disown and god knows what else to use for something which should be trvial. I recommend looking around for cli alternatives to commonly used commands in general as productivity boost as for anything to do with running processes I can't recommend btop enough I won't tell you how to use it because its actually made to be used by humans. I bet its available via package manager of your choice give it a shot you won't look back there is also very nice procs.

Hnus
  • 111
  • 2