15

if i want to display "aaa" on screen:

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

conlusion from (3) and (4) -> detached process still have connected output that can be controlled, used, redirected..., but not input!

My question is: does someone understand why and how line (5) works ???

... "<&0" is short for "0<&0", why redirecting 0 to 0 is solution, and what really happens behind with input of detached process. Subshell's are not the problem, using braces {...} instead of (...) provide same results.

... and question2: is there better solution for "giving input to detached process" than line (6).

13

Yes, as required by POSIX, commands started in background with & have their standard input redirected from /dev/null.

And indeed

{ cmd <&3 3<&- & } 3<&0

is the most obvious way to work around it.

It's not clear why you'd want to run part of pipeline in background though.

6
  • reason was to get PID of one specific command inside pipe chain ( cmd1 | { cmd2 &; pid2=$!; } | cmd3 ... , so /dev/null==&0 is standard for BG proces, do you also know why "0<&0" works in bash ... and is it safe? Apr 4 '13 at 17:50
  • 3
    @OmerMerdan POSIX says In all cases, explicit redirection of standard input shall override this activity, which contradicts somehow what it said above, so I believe bash interprets it (and that sounds like a reasonable interpretation) as cancelling the /dev/null redirection. Now, not many shells do the same. Ash and pdksh don't. Apr 4 '13 at 17:55
  • Why it the 3<&- part needed and is it safe to use it (will it not close the pipe before the full input ir read)?
    – mvorisek
    Dec 31 '17 at 16:02
  • 1
    @Mvorisek, that fd 3 is only used temporarily to restore the original stdin. We close it as cmd doesn't need it. We close it after we have dupped it onto fd 0 (<&3 short for 0<&3). Dec 31 '17 at 16:39
  • 1
    @Mvorisek, nohup also redirects stdin to /dev/null, so you'd need: { nohup sh -c 'cmd <&3 3<&-' & } 3<&0. Or (trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0 Dec 31 '17 at 16:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.