keepcalculator

06 Numbers and Powers

Bash wait Command: How It Works & When to Use It

Card No. 06·66405 · Updated · Standard formula, shown below

The Bash wait command pauses the current shell until one or more background jobs finish, then returns their exit status. You use it when you launch processes with & and need to coordinate their completion before continuing your script. This article explains the syntax, behavior, and common pitfalls of wait so you can use it reliably in your own scripts.

What the wait Command Does

wait is a shell built-in (not an external program) that makes the shell wait for background jobs to terminate. Without arguments, it waits for all currently running background jobs. With a job ID (like %1) or a process ID (PID), it waits only for that specific job. The command returns the exit status of the waited-for process, which is useful for error checking.

For example, if you run sleep 5 & and then wait, the shell will pause for 5 seconds. If the background job fails (returns non-zero), wait will return that same non-zero value, allowing your script to react.

Syntax and Arguments

The basic syntax is:

wait [job_id_or_pid ...]
  • No arguments – wait for all background jobs.
  • PID – wait for a specific process ID (e.g., wait 1234).
  • Job spec – wait for a job ID like %1 or %2.

You can pass multiple PIDs or job IDs in one command, and wait will wait for all of them. If a job has already finished, wait returns immediately with that job’s exit status.

How It Differs From sleep and Other Commands

New users often confuse wait with sleep. sleep pauses the shell for a fixed amount of time; wait pauses until an external condition (a process finishing) is met. This makes wait more efficient because you don’t have to guess how long a task will take.

Another related command is jobs, which lists active background jobs. wait does not show a list; it simply blocks. If you need to check on jobs without blocking, use jobs -l or pgrep.

Common Mistakes and Pitfalls

One frequent mistake is using wait on a process that is not a child of the current shell. wait can only wait for jobs that the shell itself started. If you try to wait on a PID from another terminal, you’ll get an error like “pid 1234 is not a child of this shell.”

Another pitfall is forgetting that wait returns the exit status of the last job waited. If you wait for multiple jobs, the return value is that of the final one, not the first failure. To catch any failure, you need to check each job individually:

job1 &
job2 &
wait $job1 || echo "Job1 failed"
wait $job2 || echo "Job2 failed"

Also, if you use set -e (exit on error), a failed background job will cause wait to exit your script. Be careful with that interaction.

Using wait in Scripts vs. Interactive Shells

In interactive shells, wait works the same way, but you rarely need it because you can just type fg to bring a job to the foreground. In scripts, wait is essential for parallel processing – e.g., running several downloads at once and then combining results.

One subtlety: if you run wait inside a for loop, it will wait for all background jobs at that point, not just the ones started in the current iteration. To wait per-iteration, store the PIDs in an array and wait on them individually.

Alternatives and Related Tools

If you need more complex coordination, consider:

  • GNU Parallel – runs jobs in parallel with better control over output and resource limits.
  • xargs -P – runs a command with a specified number of parallel processes.
  • Named pipes (FIFOs) – allow processes to signal each other without waiting for completion.

These tools are not replacements for wait in simple cases, but they offer more features when you need to manage many jobs or handle output interleaving.

Frequently Asked Questions

Can I wait for a process that isn’t a child of my shell?
No. wait only works on jobs started by the current shell. For other processes, use kill -0 to check existence, or use a polling loop with ps.

What happens if I press Ctrl+C while waiting?
If you interrupt wait, the shell receives SIGINT. The background job keeps running, but wait returns 130 (128+SIGINT). Your script can handle that with a trap.

Does wait work with pipelines?
Yes, but you need to wait on the PID of the last command in the pipeline. For example, cmd1 | cmd2 & gives you the PID of cmd2 only. To wait for the whole pipeline, use wait with no arguments.

Is there a timeout for wait?
No built-in timeout. You can implement one by running wait in a subshell with a background timer, or use timeout command around the whole script.

Why does wait return immediately when I use it in a function?
If the background job was started in a subshell (e.g., inside parentheses), it’s not a child of the current shell, so wait may not see it. Start jobs in the same shell context.

Can I wait for a job that has already been waited on?
No. Once wait has returned for a job, the shell no longer tracks it. A second wait on that PID will fail with “pid is not a child of this shell.”

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →