3

From https://unix.stackexchange.com/a/43709/674

To just kill all background jobs managed by bash, do

kill $(jobs -p)

Does kill $(jobs -p) kill only those "running" background jobs in the current shell, but not those background jobs in the shell which are in "stopped" or some other states?

How can we kill all the background jobs in the current shell, regardless of whether they are in running, stopped or some other states?

For example, I created two stopped jobs, by running less and then ctrl+z:

$ ps | less

[1]+  Stopped                 ps | less
$ less recover_jobs.sh

[2]+  Stopped                 less recover_jobs.sh

$ jobs -l
[1]-  2753 Done                    ps
      2754 Stopped                 | less
[2]+  2842 Stopped                 less recover_jobs.sh
$ jobs -p
2753
2842

$ kill $(jobs -p)
bash: kill: (2753) - No such process
$ kill 2754
$ kill 2842
$ jobs -l
[1]-  2753 Done                    ps
      2754 Stopped                 | less
[2]+  2842 Stopped                 less recover_jobs.sh

$ fg 1
ps | less
Terminated
$ fg 2
less recover_jobs.sh
Terminated

I was wondering why:

  • kill $(jobs -p) doesn't kill any stopped job,

  • jobs -p doesn't show the pid 2754 of the stopped job | less, but the pid 2753 of the done job ps,

  • kill 2754 and kill 2842 don't kill the stopped jobs for | less and for less recover_jobs.sh, and
  • when I fg the stopped jobs, they are immediately shown Terminated but not before I fg them?

Thanks.

Tim
  • 101,790

1 Answers1

4

kill $( jobs -p ) would send the TERM signal to all jobs, regardless of whether they are running or not. A job may include several processes, but only the first process in each job would be signalled (see further below).

Your first and third and last question has the same answer. A stopped job does not receive any signals. A signal handler (even the default one) runs in the process, and the process is stopped. The signals are delivered when the job resumes.

As for the second question, I believe that jobs -p only gives you the process ID of the first process in the pipeline, whereas jobs -l lists all processes belonging to all jobs. Killing the first process of a pipeline would close the file descriptor that the next process is reading from, prompting an end-of-file on its next read attempt.

Kusalananda
  • 333,661