wait is a command that waits for the given jobs to complete and returns the exit status of the waited for command.

Since the wait command affects the current shell execution environment, it is implemented as a built-in command in most shells.

In this article, we’ll explore the Bash built-in wait command.

Bash wait Command

The general syntax of the wait built-in takes the following form:

ID is the process or job ID. If no ID is specified, the command waits until all child background jobs are completed.

The wait command returns the exit status of the last command waited for.

For example, to wait for a background process with PID 7654, you would use:

wait 7654

When multiple processes are given, the command waits for all processes to complete.

Jobs are specified using the job specification (“jobspec”), which is a way to refer to the processes that make up the job. A jobspec starts with a percentage symbol followed by the job number (%n). Here is an example:

Run a command in a background :

rsync -a /home /tmp/home &

The shell job ID (surrounded with brackets) and process ID will be displayed on your terminal:

[2] 54377

To wait for the job, run the wait command followed by the job specification:

wait %2

When invoked with the -n option, the command waits only for a single job from the given pids or jobspecs to complete and returns its exit status. If no arguments are provided, wait -n waits for any background job to complete and return the job exit status.

wait -n 45432 54346 76573

In the example above, wait -n only prints the return status of the job that exits first; it doesn’t show the PID of the job. If you want to get the job pid or jobspec for which the exit status is returned, use the -p option to assign it to a variable:

wait -p job_id -n 45432 54346 76573

-p option was introduced in Bash 5.1. If you use an older Bash version, you’ll get an “invalid option” error.

The -f option tells wait to wait for each pid or jobspec to actually terminate before returning its exit code, rather than returning when the job status is changed. This option is only valid when job control is enabled. By default, job control is enabled only for interactive prompts.

Examples

wait is typically used in shell scripts that spawn child processes that execute in parallel.

To illustrate how the command works, create the following script:

#!/bin/bash
sleep 30 &
process_id=$!
echo "PID: $process_id"
wait $process_id
echo "Exit status: $?"

Let’s explain the code line by line:

  1. The first line is called shebang and tells the operating system which interpreter to use to parse the rest of the file.
  2. We are using the sleep command to emulate a time-consuming background process.
  3. $! is an internal Bash variable that stores the PID of the last job run in the background. In this example, that is the PID of the sleep command. We’re storing the PID in a variable (process_id).
  4. Prints the PID number.
  5. The PID is passed to the wait command that waits until the sleep command completes.
  6. Prints the exit status of the wait command. $? is an internal Bash variable that holds the exit status of the last command executed.

If you run the script, it will print something like this:

PID: 36353
Exit status: 0

Here an example using the -n option:

#!/bin/bash
sleep 3 &
sleep 30 &
sleep 5 &
wait -n
echo "First job completed."
wait
echo "All jobs completed."

When the script is executed, it spawns 3 background processes. wait -n waits until the first job is completed and the echo statement is printed. wait waits for all child background jobs to complete.

first job completed
all jobs completed

The last example explains the -f option. Open the terminal and run:

sleep 3600 &
[1] 46671

Wait for the process:

wait 46671

Open another terminal and stop the process with the kill command:

kill -STOP 46671

Once the process status is changed, the wait command will complete and return the process exit code.

Now, repeat the same steps, but this time use wait -f $pid:

sleep 3600 &wait -f 46671

Stop the process from the other terminal:

kill -STOP 46671

This time the wait command will not complete. It will run until the sleep process terminates.

Conclusion

The wait command waits for the specified jobs to complete and returns the exit code of the job.

If you have any questions or feedback, feel free to leave a comment.