bug: background jobs have their inputs bound to `/dev/null`, even in the face of explicit redirection
Pablo Repetto <[email protected]> Sun, 15 Dec 2024 19:16:15 -0300
| Newsgroups | org.kernel.vger.dash |
|---|---|
| Message-ID | <CAFKqKCrEXCkyFTx8SqOHx=LHYyKpfa6scjcrMCxA=Hoo0p9yMA@mail.gmail.com> |
# AFFECTED VERSION
`apt show dash` returns `Version:
0.5.11+git20210903+057cd650a4ed-3build1`, several other versions
likely affected
# PROBLEM DESCRIPTION
Background jobs have their inputs bound to `/dev/null`, even in the face
of explicit redirection
```
# the following produces no output, both are erroneous
echo x | { cat & wait; }
echo x | { <&0 cat & wait; }
```
```
# the following (correctly) produces no output
echo x | /bin/dash -c "cat & wait"
```
# SUPPORTING EXCERPTS FROM POSIX.1-2024
Relevant sections in the POSIX standard:
- shell & utilities, 2.9.3 Lists, Asynchronous lists
- shell & utilities, 2.13 Shell Execution Environment
- shell & utilities, 2.9.4 Compound Commands
('08 version has different section numbers, but the cotent seems equivalent)
> Utilities [...] shall be invoked in a separate environment that consists of the following. The initial value of these objects shall be the same as that for the parent shell, except as noted below.
>
> - Open files inherited on invocation of the shell, open files controlled by the exec special built-in plus any modifications, and additions specified by any redirections to the utility
> - [...]
>
> shell & utilities, 2.13
> [...] asynchronous AND-OR lists shall be executed in a subshell environment. Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. [...]
>
> shell & utilities, 2.13
> If, and only if, job control is disabled, the standard input for the subshell in which an asynchronous AND-OR list is executed shall initially be assigned to an open file description that behaves as if /dev/null had been opened for reading only. This initial assignment shall be overridden by any explicit redirection of standard input within the AND-OR list.
>
> shell & utilities, 2.9.3
(both `<&0` and `|` should count as explicit redirection, see "Other
Supporting Evidence")
> [...] Each redirection shall apply to all the commands within the compound command that do not explicitly override that redirection. [...]
>
> shell & utilities, 2.9.4
(so in `echo x | { cat & cat & wait; }` both instances of `cat` should
have their stdin bound to the stdout of `echo`, resulting in contention
and possible input interleaving. the question of IO atomicity is
also discussed in the standard, but irrelevant to the current issue)
# OTHER SUPPORTING EVIDENCE
bash received a closely related bug report in 2016. Both the discussion
on whether a pipeline into a compound command counts as explicit redirection
and the ultimate patch applied are extremely relevant.
https://groups.google.com/g/gnu.bash.bug/c/bgTSFM8UAek