Having problems redirecting stderr to a subshell created w/process substitution

570 views Asked by At
~ bash --version
GNU bash, version 3.2.51(1)-release (sparc-sun-solaris2.10)
Copyright (C) 2007 Free Software Foundation, Inc.

The following command works as expected:

~ ls hdfhdfhdhfd 2> >(wc -l)
1

... but this doesn't work, and I'm running out of ideas to figure out why:

~ truss -eaf bash -c 'true' 2> >( some command to process text)

The command inside the >() ends up blocking waiting for input.

If I do this instead:

~ (true; truss -eaf bash -c 'true') 2> >( some command )

... it works as expected, though this doesn't work:

~ (      truss -eaf bash -c 'true') 2> >( some command )
#  ^^^^^ ... note the 1st command is missing

If I make some command = dd bs=1, it consumes and prints all text truss would've spat out on stderr, then blocks.

I cannot reproduce similar behavior in Linux, only when using truss in solaris.

1

There are 1 answers

0
Brian Vandenberg On BEST ANSWER

Based on @ccarton's response I've come up with a rough idea of what's happening. To illustrate:

~ truss -eaf /usr/bin/perl -e 'print "Test\n"; sleep 5' 2> >(dd bs=1 | wc -l)

In another terminal I could see this parent/child hierarchy:

  1. bash
    1. truss -eaf /usr/bin/perl -e printf "Test\n"; sleep 5
      1. /usr/bin/perl -e printf "Test\n"; sleep 5
      2. bash
        1. dd bs=1
          1. wc -l

truss is waiting on the shell, but dd won't exit until its stdin is closed ... so they deadlock.

~ truss -eaf -o >(some command) another command

... causes some command to execute under the current shell so truss is never its ancestor.

I saw the same hierarchy in Linux, but it doesn't deadlock.