如何解决POSIX sh:复合命令如何与管道一起使用?
我试图了解顺序命令组(在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()实现正确的行为?
解决方法
if test-expr1; then
cmd1; cmd2; cmd3; ...
fi | { cmd4; cmd5; ...; } | cmd6
将在解析树中呈现为:
_______________|
/ \
________________|___ \
/ \ \
IF__________________ \ \
/ \ \ \ \
test-expr1 cmd1; cmd2; cmd3 (nil) cmd4; cmd5; cmd6
看着叶子
- test-expr1:如果涉及运行命令,则可能会分叉,否则不需要。
- cmd1; ...:可能是叉子,除非它们是内部零件。一个分叉的外壳可以按顺序运行这些命令
- cmd4; cmd5:可能是fork,除非内部。一个分叉的外壳可以运行这些序列。
- 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
,
这是不正确的,因为即使在管道命令列表中,echo $$仍然报告相同的PID。
这是正确的,并且您检查的方法不正确。来自bash manual:
($$)扩展为Shell的进程ID。在()子外壳程序中,它扩展为调用外壳程序的进程ID,而不是子外壳程序。
因此,您检查了调用外壳程序在所有子外壳程序中是否相同。是的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。