通常,Unix 中的管道用于连接两个命令,并将第一个命令的输出作为第二个命令的输入。然而,我最近提出了使用管道并行运行多个命令的想法(这可能并不新鲜,但我没有找到太多谷歌搜索),如下所示:
command1 | command2
这将并行调用command1
和command2
ifcommand2
不从标准输入读取也不command1
写入标准输出t. 一个最小的例子来说明这一点(请在交互式 shell 中运行它)
ls . -R 1>&2|ls . -R
我的问题是,使用管道以这种方式并行执行两个命令有什么缺点吗?这个想法有什么我错过的吗?
预先非常感谢您。
答案1
命令管道已经并行运行。使用命令:
command1 | command2
command1
和都已command2
启动。如果command2
已调度且管道为空,则它会阻塞等待读取。如果command1
尝试写入管道且管道已满,command1
则会阻塞,直到有空间可写入。否则,command1
和command2
都会并行执行,写入管道和从管道读取。
答案2
有缺点...
- 你看不到的输出
command1
- 如果
command2
不读取 的输出command1
,后者将在写入一定量的输出后挂起(我见过 4K,但根据实验,至少对于 python 进程来说,限制在 58K 左右,见下文)。这可能取决于 所使用的运行时command1
。 - 如果
command2
之前停止command1
并command1
写入其标准输出,它将得到[Errno 32] Broken pipe
实验:
指令1#! /usr/bin/python3
import sys,time
for i in range(64):
print ("*"*1023,file=sys.stdout)
print ("cmd1 here (%d)" % i,file=sys.stderr)
time.sleep(.1)
print ("cmd1 exiting",file=sys.stderr)
指令2
#! /usr/bin/python3
import sys,time
for i in range(16):
print ("cmd2 here (%d)" % i,file=sys.stderr)
time.sleep(1)
print ("cmd2 exiting",file=sys.stderr)
跑步:
./cmd1 | ./cmd2
你会看见:
cmd1
在迭代 58 处停止(因为 cmd2 从未从其输出中读取任何内容)cmd1
cmd2 退出时崩溃(管道损坏)
所以是的,也许它可以起作用。也许不是。