我试图了解顺序命令组(在GNU bash手册中称为“列表”)如何与POSIX sh定义或其实现中的管道一起使用。例如,以下代码:
if test-expr1; then
cmd1; cmd2; cmd3; ...
fi | { cmd4; cmd5; ...; } | cmd6
此处,管道具有两个顺序的“列表”和一个命令,其中cmd2
在cmd1
完成后执行,cmd5
在cmd4
之后执行。但是,所有这三个都是并行运行的,因此管道不会阻塞。
我的第一个猜测是,为每个“列表”创建了一个带有单独PID的子shell,该子shell按顺序执行所有命令,但不会阻止shell产生其他进程-如果shell发生了开始等待cmd1
完成。不过,这是错误的,因为echo $$
即使在管道命令列表中仍然报告相同的PID。
问题是:到底如何使用fork()/ waitpid()实现正确的行为?
答案 0 :(得分:0)
if test-expr1; then
cmd1; cmd2; cmd3; ...
fi | { cmd4; cmd5; ...; } | cmd6
将在解析树中呈现为:
_______________|
/ \
________________|___ \
/ \ \
IF__________________ \ \
/ \ \ \ \
test-expr1 cmd1; cmd2; cmd3 (nil) cmd4; cmd5; cmd6
看着叶子
将IF statemnet(1、2)输送到(3)中。 (3)被传送到4。因此,如果您的命令是:
if /bin/echo You; then /bin/echo say; /bin/echo hi; fi | { cat -; echo I; echo say; echo Lo; } | cat -;
您将得到输出:
You
say
hi
I
say
Lo
答案 1 :(得分:0)
这是不正确的,因为即使在管道命令列表中,echo $$仍然报告相同的PID。
这是正确的,并且您检查的方法不正确。来自bash manual:
($$)扩展为Shell的进程ID。在()子外壳程序中,它扩展为调用外壳程序的进程ID,而不是子外壳程序。
因此,您检查了调用外壳程序在所有子外壳程序中是否相同。是的。