• ksh93: pipelines vs. job control

    From Christian Weisgerber@21:1/5 to All on Mon May 13 14:35:32 2024
    ... 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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Martijn Dekker@21:1/5 to All on Sun May 19 20:21:06 2024
    Op 13-05-2024 om 15:35 schreef Christian Weisgerber:
    ... 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

    In my view, this is certainly a bug. The shell should not hang under any circumstances. I've filed it under:

    https://github.com/ksh93/ksh/issues/750

    and we'll try to find a fix or workaround for it eventually.

    --
    || modernish -- harness the shell
    || https://github.com/modernish/modernish
    ||
    || KornShell lives!
    || https://github.com/ksh93/ksh

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)