8

Say I have multiple bash scripts that run in parallel, with code like the following:

#!/bin/bash

tail -f /dev/null &
echo "pid is "$!

Is $! guaranteed to give me the PID of the most recent background task in that script, or is it the most recent background task globally? I'm just curious if relying on this feature can cause race conditions when the PID it returns is from a process started in another script.

16

$! is guaranteed to give you the pid of the process in which the shell executed that tail command. Shells are single threaded, each shell lives in its own process with its own set of variables. There's no way the $! of one shell is going to leak into another shell, just like assigning a shell variable in one shell is not going to affect the variable of the same name in another shell (if we set aside the universal variables of the fish shell).

Now, tail -f /dev/null is a command that runs indefinitely, but for short-lived commands, note that since there's a limited number of possible process ids, process ids inevitably end up being reused.

In:

true &
pid=$!

That $pid will contain the id of the process where the shell ran true, but by the time you use that $pid, that pid may well be dead and could be referring to a different process.

  • 3
    Yep I was aware of your second point, and that if you want to make a reliable background process manager you need to use a language that guarantees you will know the exact moment when a child process has exited and its PID has been returned to the pool, which apparently shell scripts cannot since they reap child processes aggressively. Thank you for the clear explanation. – philraj Aug 25 at 16:48
  • 5
    @philraj, in zsh, you can install handlers on SIGCHLD which are processed upon termination of asynchronous jobs and use $jobstate/$jobtext to inspect process status there. Not without race as the child is already reaped at the time the trap is executed, but that means very short race windows where pids are very unlikely to already be reused. – Stéphane Chazelas Aug 25 at 17:01

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.