How do I use the watch and jobs commands together in Bash?

How do I use the watch command with jobs command, so that I can monitor when a background job is finished?

I execute it as follows, but I do not get the output from jobs:

watch jobs

If I run jobs by itself, I get the following with my test background job:

jobs
[1]+  Running                 nohup cat /dev/random >/dev/null &

Solution 1:

The watch command is documented as follows:

SYNOPSIS
   watch  [-dhvt]  [-n  <seconds>] [--differences[=cumulative]] [--help]
          [--interval=<sec-onds>] [--no-title] [--version] <command>
[...]
NOTE
   Note that command is given to "sh -c" which means that you may need to
   use extra quoting to get the desired effect.

The part about giving the command to sh -c means the jobs command you are running via watch is running in a different shell session than the one that spawned the job, so it cannot be seen that other shell. The problem is fundamentally that jobs is a shell built-in and must be run in the shell that spawned the jobs you want to see.

The closest you can get is to use a while loop in the shell that spawned the job:

$ while true; do jobs; sleep 10; done

You could define a function in your shell startup script to make that easier to use:

myjobwatch() { while true; do jobs; sleep 5; done; }

Then you just have to type myjobwatch.

Solution 2:

Rather than a loop, I tend to use watch with a grep for my running job, eg

watch 'ps u | grep rsync'

Not perfect, but better than a while loop :)

Solution 3:

You could use a while loop and make a function for this command:

while true; do echo -ne "`jobs`\r"; sleep 1;  done