Sujet : ksh93: pipelines vs. job control
De : naddy (at) *nospam* mips.inka.de (Christian Weisgerber)
Groupes : comp.unix.shellDate : 13. May 2024, 16:35:32
Autres entêtes
Message-ID : <slrnv4499k.30g3.naddy@lorvorc.mips.inka.de>
User-Agent : slrn/1.0.3 (FreeBSD)
.... or "how to accidentally hang your ksh93 session".
Bash has this shell option:
lastpipe
If set, and job control is not active, the shell runs
the last command of a pipeline not executed in the
background in the current shell environment.
The bit about job control sounds like a weird stipulation, but makes
sense once you think about it. I wonder how ksh93 handles that.
Famously, the AT&T ksh executes the last command of a pipeline in
the current shell:
$ x=foo
$ { /bin/sleep 10; echo bar; } | read x
$ echo $x
bar
However, a background pipeline runs in a subshell, as documented
in the man page:
$ x=foo
$ { /bin/sleep 10; echo bar; } | read x &
[1] 78726
$
[1] + Done { /bin/sleep 10; echo bar; } | read x &
$ echo $x
foo
But we are in job control environment. I can start a pipeline in
the foreground, suspend it, and put it into the background. ksh93
can't know about that in advance.
$ { /bin/sleep 10; echo bar; } | read x
^Z
... and now the pipeline is suspended...
PID PGID STAT COMMAND
71496 71496 S - ksh93 ksh93
62980 62980 T+ `-- ksh93 ksh93
3778 62980 T+p `-- /bin/sleep 10
... and you're stuck. There's no shell prompt, so you can't bg or fg
anything, intr (^C) or quit (^\) don't help, and there's no tty
control character to continue a suspended process (group).
You need to take radical measures like hanging up, or sending a
SIGCONT or SIGKILL from a different terminal.
I can't quite tell if this behavior constitutes a bug, but it seems
to follow from the design decision to not run the last command of
a pipeline in a subshell. And it can trap the unwary.
A more minimal example:
$ /bin/sleep 10 | read
^Z
PID PGID STAT COMMAND
30796 30796 S - ksh93 ksh93
31981 31981 T+p `-- /bin/sleep 10
-- Christian "naddy" Weisgerber naddy@mips.inka.de