-1

I'm facing an unexpected behaviour of the wait builtin.

~
❯ sleep 1 &
[1] 72009

~
❯
[1]  + 72009 done       sleep 1

~
❯ wait 72009

~
❯ echo $?
0

Although the PID doesn't exist anymore wait still exits with zero exit status.

Questions

  • What is the reason for this behaviour?
  • How does wait works? What does it do behind the scenes?
1

Bash’s wait returns 0 in this case because it “remembers” that process 72009 was one of its children, and it remembers its children’s exit codes, and that exit code was 0. (The documentation is somewhat misleading here since it mentions “active” processes explicitly.)

Behind the scenes, wait determines whether a given process identifier corresponds to one of the shell’s children, perhaps in a job; if so, it checks whether the process is still running. If it’s still running, it waits for it to finish. Once it’s finished, it determines the corresponding exit code (which could be for the process only, or for the job as a whole), and returns that. There’s a lot of additional complexity to deal with signals correctly, process substitution, controlling terminals etc. but that’s not relevant here.

The exit code is remembered (at least) in the job table. You can see this in action by running two commands with different exit codes (false & and true &), and waiting for the respective process identifiers. As long as the job table isn’t cleared, wait will give the correct exit code. Run wait with no argument to remove finished jobs from the job table, and you’ll see that you can no longer retrieve the exit codes of the earlier jobs.

  • Is there a way for me to see the job table? Thanks for such a detailed answer. – Shachar Ashkenazi Jul 18 '18 at 12:28
  • There’s a jobs command which shows the job table, but it only lists active jobs, and the first thing it does is to clean the job table (which removes inactive jobs). So you can’t use it to see exit codes of completed jobs. – Stephen Kitt Jul 18 '18 at 12:33
  • I know jobs only lists active jobs. I'm just wondering how can I see inactive jobs. I guess it is stored somewhere in the filesystem. – Shachar Ashkenazi Jul 18 '18 at 12:38
  • No, it’s stored in memory by each shell. Looking at the bash source code you’d have to add your own command to do so... – Stephen Kitt Jul 18 '18 at 12:42
-1

This is how the wait builtin in the shell is defined.

  • waiting for children that already have been terminated causes wait to return 0.

Some shells (e.g. ksh93) have a cache for the last few processes and may return the exit code for such children.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.