后台进程替换

后台进程替换

这个问题来自https://mywiki.wooledge.org/ProcessSubstitution

mkfifo /var/tmp/fifo1
mkfifo /var/tmp/fifo2
sort list1 >/var/tmp/fifo1 &
sort list2 >/var/tmp/fifo2 &
diff /var/tmp/fifo1 /var/tmp/fifo2
rm /var/tmp/fifo1 /var/tmp/fifo2

据我了解命名管道,我认为以下内容有效:

在第 1-2 行中,我们创建了两个命名管道:fifo1 和 fifo2。

sort list1 > fifo1 &sort list2 > fifo2 &尝试写入命名管道,因此它们会被阻塞,直到从其中读取数据为止。

然后diff接下来的命令从 fifo1 和 fifo2 读取。所以3-4号线畅通无阻。接下来diff执行并将输出发送到终端。

最后,我们删除命名管道 fifo1 和 fifo2。

消息人士称,这一切都与diff <(sort list1) <(sort list2).

我的解释正确吗?

谢谢!

答案1

我的解释正确吗?

不会。sorts 甚至在启动之前就被阻止了(sort当尝试执行 s 时,执行 s 的子 shell 会被阻止)打开先进先出)。它们只会被阻塞,直到 fifo 的另一侧被阻塞打开也没有必要从中得到任何东西。

如果您尝试mkfifo /tmp/fifo; true > /tmp/fifotrue即使它从未尝试向 fifo 写入任何内容,也会被阻止。来自另一个 shell 的Atrue < /tmp/fifo将解锁它,而不尝试任何事情。

消息人士称,这一切都与diff <(sort list1) <(sort list2).

它不是。如果由于某种原因diff fifo1 fifo2在打开作为参数传递的 fifo 之前终止,它们sort ... &将永远留在那里,直到有人怜悯并手动杀死它们。

我不知道进程替换是否真的可以用命名管道来实现,但 FWIW bash 并没有轻易实现这一点;在没有 s 的平台上/dev/fd,bash 的进程替换是有缺陷的,并且只能非常小心地使用。

相关内容