如何使管道顺序运行

123*_*123 2 unix linux bash pipe

眼镜

不要认为这应该有所作为,但无论如何我都会包括它

GNU bash,版本3.2.51


前提

所以说我有一个包含多个部件的管道,如何防止部分管道在前一个部件完成之前运行.


在下面的例子中,我将尝试显示问题

$ echo hello | tee /dev/tty | (echo "Next";sed 's/h/m/' )
Run Code Online (Sandbox Code Playgroud)

产量

Next
hello
mello
Run Code Online (Sandbox Code Playgroud)

用睡眠来表明它是关闭的时间

$ echo hello | tee /dev/tty | (sleep 2;echo "Next";sed 's/h/m/' )
Run Code Online (Sandbox Code Playgroud)

产量

hello
Next
mello
Run Code Online (Sandbox Code Playgroud)

预期产出

如上所述

hello
Next
mello
Run Code Online (Sandbox Code Playgroud)

但显然这取决于睡眠时间长于前一个命令完成所需的时间,这不是我想要的.


笔记

我知道有更好的方法可以做到这一点,但我认为让我了解管道的工作方式对我来说很有教育意义.


试着

尝试等待和睡眠的变化和事情,但没有一致的工作.


l0b0的建议

这仍然打印下一个虽然

$ echo hello | tee /dev/tty | sort |(echo "Next";sed 's/h/m/' )
Next
hello
mello

$ echo hello | tee /dev/tty | tac | tac |(echo "Next";sed 's/h/m/' )
Next
hello
mello
Run Code Online (Sandbox Code Playgroud)

如果需要更多信息,请告诉我.

l0b*_*0b0 5

管道的要点是异步处理数据,以便整体节省时间和空间.如果您想要一个同步管道,您也可以写入文件(如果您需要速度,则在RAM磁盘上).但是对于接收命令能够处理数据块的任务,完整的管道可能要慢得多:

  1. a | b | c 最多可以和三个命令中最慢的一样快.
  2. a > file; b < file > file2; c < file2最多可以与每个命令的运行时总和一样快.

因此,如果命令全部在大约N秒内运行(当单独运行时),那么您将查看第一个命令的N的最佳案例运行时和第二个命令的3N.


che*_*ner 3

没有语言构造可以bash像您想要的那样修改管道的行为。但是,您可以使用命名管道充当一种二进制信号量:

mkfifo block
echo hello | 
  { tee /dev/tty; echo go > block; }  |
  (read < block; echo "Next"; sed 's/h/m/' )
Run Code Online (Sandbox Code Playgroud)

read命令会阻塞,直到有东西写入命名管道,直到完成为止tee

(请注意,这可能无法完全解决您的问题,因为除了进程同步之外,您可能还需要应对以下事实:您有多个进程写入同一个输出文件,并且您无法完全控制各个进程如何写入是多路复用的(由于缓冲等)