Search code examples
bashjobs

Bash: check job is finished


Theoretical question. Can someone explain me why jobs keep returning Done when it's already done?

root@test:~# cat 1.sh
#!/bin/bash

sleep 5 &
while true; do
  echo $(jobs) && sleep 1
done

root@test:~# ./1.sh
[1]+ Running sleep 5 &
[1]+ Running sleep 5 &
[1]+ Running sleep 5 &
[1]+ Running sleep 5 &
[1]+ Running sleep 5 &
[1]+ Done sleep 5
[1]+ Done sleep 5
[1]+ Done sleep 5
[1]+ Done sleep 5
^C

GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)


Solution

  • Because job control is disabled in scripts, bash ignores signal SIGCHLD and is not notified (and doesn't want to) about terminating background processes.

    Because jobs is executed inside a subshell, the parent shell environment doesn't know that the last jobs already checked the child exit status and that the child terminated. Because of that, each time a new subshell is created, it's fresh environment is not aware that the message was printed, so it prints another one.