Does POSIX sh require expanding $! in order to keep a reference to the child process?
1
vote
1
answer
113
views
## Spec
According to [this online POSIX Spec](https://pubs.opengroup.org/onlinepubs/9699919799/) , in Shell & Utilities, Shell Command Language, Section 2.9.3 Lists has the following to say about Asynchronous Lists:
> When an element of an asynchronous list (the portion of the list ended
> by an \, such as *command1*, above) is started by the shell,
> the process ID of the last command in the asynchronous list element
> shall become known in the current shell execution environment; see
> Shell Execution Environment. This process ID shall remain known until:
>
> - The command terminates and the application waits for the process ID.
>
> - Another asynchronous list is invoked before "
$!
" (corresponding to the
> previous asynchronous list) is expanded in the current execution
> environment.
>
> The implementation need not retain more than the {CHILD_MAX} most
> recent entries in its list of known process IDs in the current shell
> execution environment.
Other relevant quotations:
- From idem., Section 2.12 Shell Execution Environment:
> A shell execution environment consists of the following:
>
> […]
>
> - Process IDs of the last commands in asynchronous lists known to this shell environment; see Asynchronous Lists
- From Shell & Utilities, Utilities, wait:
> When an asynchronous list (see Asynchronous Lists) is started by the shell, the process ID of the last command in each element of the asynchronous list shall become known in the current shell execution environment; see Shell Execution Environment.
>
> […]
>
> If the wait utility is invoked with no operands, it shall wait until all process IDs known to the invoking shell have terminated and exit with a zero exit status.
>
> […]
>
> The known process IDs are applicable only for invocations of wait in the current shell execution environment.
## Confusion
In Bash, help wait
specifies "all currently active child processes."
The spec specifies only all known process IDs, and it seems that that invoking another async list causes the process ID to be "forgotten."
That would make the following program only wait for 5 seconds if I've interpreted the POSIX spec correctly:
#! /bin/sh
sleep 10 &
sleep 5 &
wait
Since no use of $!
appears before sleep 5 &
, is the ID for sleep 10
forgotten and not waited on?
Similarly, inserting : $!
between the two lines would cause it to not be forgotten, right?
Let me try to lay out my logic a little more clearly:
1. SPEC: The known proc. IDs are part of the shell execution environment. Let's imagine this is some list, since implementation details don't matter.
1. SPEC: Running command &
causes the proc. ID for this asynchronous command
to be "known" (_i.e._, in the list).
- SPEC (dubiously, but see the very first quote): Running command2 &
without expanding $!
in some way causes the proc. ID for the previous command to become _no longer known_! (But the proc. ID for command2
is now known.)
1. SPEC: wait
with no arguments uses only the known proc. IDs.
1. Conclusion: Therefore, not forcing expansion of $!
between asynchronous commands causes wait
to forget to wait on some child processes.
Some have argued that wait
waits on all processes. The spec says "known" processes, which has a specific definition. Some have argued that "known" refers to "in $!" even though the spec says no such thing (and further, "known process IDs" is a plural quantity while $!
is not).
I agree this makes no practical sense; a shell doesn't forget about my jobs when I start a new one. So where am I misreading the spec?
## Question
- Does POSIX actually require using $!
in order for wait
with no arguments to behave sensibly, such as when starting asynchronous lists in a loop?
- Does any shell (POSIX or otherwise) actually implement the spec in such a way (_i.e._, practically, can I avoid adding : $! expand async. proc. ID to prevent forgetting it
to programs that use nullary wait
)?
Asked by D. Ben Knoble
(552 rep)
Apr 24, 2023, 05:06 PM
Last activity: Apr 24, 2023, 06:52 PM
Last activity: Apr 24, 2023, 06:52 PM