后台进程管道输入


14

如果我想在屏幕上显示“ aaa”:

(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

(3)和(4)->分离过程的结果仍然具有可以控制,使用,重定向的连接输出,但是没有输入!

我的问题是:有人了解第(5)行的原因和方式吗?

...“ <&0”是“ 0 <&0”的缩写,为什么将0重定向到0是解决方案,以及在输入分离过程后真正发生了什么。Subshel​​l并不是问题,使用大括号{...}代替(...)可以提供相同的结果。

...和问题2:是否有比“第6行”更好的“向分离过程提供输入”的解决方案。

Answers:


12

是的,根据POSIX的要求,在后台启动的命令&的标准输入从重定向/dev/null

的确

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

是解决它的最明显的方法。

目前尚不清楚为什么要在后台运行部分管道。


原因是要在管道链中获取一个特定命令的PID(cmd1 | {cmd2&; pid2 = $ !;} | cmd3 ...,所以/ dev / null ==&0是BG过程的标准,您还知道为什么吗“ 0 <&0”在bash中起作用...并且安全吗?
Asain Kujovic

3
@OmerMerdan POSIX表示,在所有情况下,标准输入的显式重定向都将覆盖此活动,这在某种程度上与上面所说的相矛盾,因此我相信bash将其解释为(这听起来像是一种合理的解释)取消了/dev/null重定向。现在,没有多少壳可以做到这一点。Ash和pdksh不会。
斯特凡Chazelas

为什么需要该3<&-零件,使用起来是否安全(在读取完整的输入ir之前,它不会关闭管道)吗?
mvorisek

1
@ Mvorisek,fd 3仅用于恢复原始标准输入。我们关闭它cmd不需要它。将其翻倍到fd 0(<&3缩写0<&3)后,我们将其关闭。
斯特凡Chazelas

1
@Mvorisek,nohup还将stdin重定向到/ dev / null,因此您需要:{ nohup sh -c 'cmd <&3 3<&-' & } 3<&0。或者(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.