[Toybox] Would someone please explain what bash is doing here?

Rob Landley rob at landley.net
Fri Apr 24 12:07:46 PDT 2020



On 4/24/20 10:55 AM, Chet Ramey wrote:
> On 4/24/20 9:48 AM, Rob Landley wrote:
>> Try this in bash, and hit ctrl-Z before it returns:
>>
>>   /bin/echo $(ls /usr/bin; sleep 5)
>>
>> Now try to get your terminal back. (Prompt doesn't come back, timeout doesn't
>> happen, ctrl-c doesn't work...)
> 
> It has no effect. The command substitution isn't a job, and it's in the
> same process group as the parent shell (as is the terminal). It's run by
> the parent before it forks to run /bin/echo.
> 
> Hitting ^C kills it.

Yes and no:

  $ /bin/echo $(sleep 5)
  ^Z^C
  $ /bin/echo $(ls /usr/bin; sleep 5)
  ^Z^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C

If something produces enough pending output to clog the pipe, then no, ctrl-C
doesn't kill it after the ctrl-Z. (Hence using /usr/bin which should reliably
have enough contents to do so.) No idea what's going on under the covers.
Unfortunately, strace isn't helpful because of course:

  $ bash -c '/bin/echo $(ls /usr/bin; sleep 5)'
  ^Z
  [1]+  Stopped                 bash -c '/bin/echo $(ls /usr/bin; sleep 5)'

It _looks_ like what's happening is ctrl-z is actually suspending the active
shell attached to the terminal, and thus you don't get the prompt back. Hmmm...

  $ echo $$
  17914
  $ /bin/echo $(ls /usr/bin; sleep 5)
  ^Z^C^C^C^C^C

[and in another terminal]

  $ kill -CONT 17914
  $ ps 17914
    PID TTY      STAT   TIME COMMAND
  17914 pts/91   Ss     0:00 bash
  $ kill -CONT 17914
  $ kill -CONT 17914

Not resuming it. Not looping eating CPU either...

  $ ps ax | grep sleep
   1347 pts/29   T+     0:00 sleep 5
   1407 pts/12   T+     0:00 sleep 5
  18320 pts/91   T+     0:00 sleep 5

Ah-ha! What on earth is...

               T    stopped by job control signal

Right.

  $ kill -CONT 18320

THAT unblocked/resumed it. (The pending ctrl-C were still ignored, it spat out
the ls output instead. Yes Linux should probably wake up stopped jobs when their
tty closes, but it doesn't.)

> I tested on Mac OS using bash-5.0 and bash-4.4. I'm not really interested
> in testing versions before that.

  $ bash --version
  GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

Devuan ascii 2.0 which is basically debian.

*shrug* If it doesn't reproduce for you, it doesn't reproduce. Seems impolite
_not_ to mention these things when I hit 'em since you've been so helpful.

This is just collateral damage while I'm still off testing 8 gazillion corner
cases trying to figure out the order of operations in ${a/b/c} style decorated
variable resolution. I've had to rip out and redo largeish chunks of my variable
resolution code TWICE since starting down this sinkhole:

  $ chicken() { echo ${*/b c/ghi}; }; chicken a b c d
  a b c d

(On the bright side, that made me finally understand what bash means with its
array stuff: on the resolution side it's just recycling the $@ plumbing it
already had to implement, which already got genericized for ${!bork}. Still
dunno what the associative arrays mean but it SMELLS like I can just store
keyword=value contents in that array and recycle the variable resolution logic.
Yeah it's not a hash table, but it's _small_ and the common case is <5k entries
which is cache local on a modern processor anyway. Wait for somebody to complain...)

Rob



More information about the Toybox mailing list