Skip to main content
added 369 characters in body
Source Link
finefoot
  • 3.6k
  • 4
  • 30
  • 56

It looks like the issue is, as suspected, trying to pipe external_program into a detached tee.

In the original script, there was:

printf %s\\n bar | tee foo &

Which doesn't detach tee (only), but the whole pipe sequence in one. So what I originally did was a pipe like this, which gets resolved immediately, i.e. both sleep and noop : get detached together:

$ time sh -c 'sleep 10 | : &'

real    0m0.001s
user    0m0.000s
sys     0m0.001s

Compared toHowever, when detaching tee only inside the function, it was only tee that got detached, not the external program at the beginning of the pipe. Re-using the example with sleep, we can see that only noop : gets detached, but sleep does not, and the script takes the full 10 seconds:

$ time sh -c 'sleep 10 | { : & }'

real    0m10.002s
user    0m0.002s
sys     0m0.000s

The solution is to not detach tee, but the other command:

f() (
  mkfifo foo
  tr -s '[:lower:]' '[:upper:]' <foo &
  tee foo
  wait
  rm foo
)
printf %s\\n bar | f

Now tee can receive stdout from the pipe, write to the FIFO, and the output of the function is again:

bar
BAR

It looks like the issue is, as suspected, trying to pipe external_program into a detached tee.

In the original script, there was:

printf %s\\n bar | tee foo &

Which doesn't detach tee (only), but the whole pipe sequence in one. So what I originally did was a pipe like this, which gets resolved immediately:

$ time sh -c 'sleep 10 | : &'

real    0m0.001s
user    0m0.000s
sys     0m0.001s

Compared to when detaching tee only inside the function:

$ time sh -c 'sleep 10 | { : & }'

real    0m10.002s
user    0m0.002s
sys     0m0.000s

The solution is to not detach tee, but the other command:

f() (
  mkfifo foo
  tr -s '[:lower:]' '[:upper:]' <foo &
  tee foo
  rm foo
)
printf %s\\n bar | f

Now the output is again:

bar
BAR

It looks like the issue is, as suspected, trying to pipe external_program into a detached tee.

In the original script, there was:

printf %s\\n bar | tee foo &

Which doesn't detach tee (only), but the whole pipe sequence in one. So what I originally did was a pipe like this, which gets resolved immediately, i.e. both sleep and noop : get detached together:

$ time sh -c 'sleep 10 | : &'

real    0m0.001s
user    0m0.000s
sys     0m0.001s

However, when detaching tee inside the function, it was only tee that got detached, not the external program at the beginning of the pipe. Re-using the example with sleep, we can see that only noop : gets detached, but sleep does not, and the script takes the full 10 seconds:

$ time sh -c 'sleep 10 | { : & }'

real    0m10.002s
user    0m0.002s
sys     0m0.000s

The solution is to not detach tee, but the other command:

f() (
  mkfifo foo
  tr -s '[:lower:]' '[:upper:]' <foo &
  tee foo
  wait
  rm foo
)
printf %s\\n bar | f

Now tee can receive stdout from the pipe, write to the FIFO, and the output of the function is again:

bar
BAR
Source Link
finefoot
  • 3.6k
  • 4
  • 30
  • 56

It looks like the issue is, as suspected, trying to pipe external_program into a detached tee.

In the original script, there was:

printf %s\\n bar | tee foo &

Which doesn't detach tee (only), but the whole pipe sequence in one. So what I originally did was a pipe like this, which gets resolved immediately:

$ time sh -c 'sleep 10 | : &'

real    0m0.001s
user    0m0.000s
sys     0m0.001s

Compared to when detaching tee only inside the function:

$ time sh -c 'sleep 10 | { : & }'

real    0m10.002s
user    0m0.002s
sys     0m0.000s

The solution is to not detach tee, but the other command:

f() (
  mkfifo foo
  tr -s '[:lower:]' '[:upper:]' <foo &
  tee foo
  rm foo
)
printf %s\\n bar | f

Now the output is again:

bar
BAR