BASH嵌套进程替换

4
我将尝试使用进程替换的标准输出在while循环中进行操作,如下所示:
#!/bin/bash

FILE_1=f1.txt
FILE_2=f2.txt

while read LINE; do
    echo "$LINE"
done < <(paste <(tail -f "$FILE_1") <(tail -f "$FILE_2"))

它的目的是在文件 FILE_1 和 FILE_2 中添加新数据时合并最后几行。显然,我想做的不仅仅是在 while 循环中打印一行,但这是一个很好的例子。

不幸的是,当我运行这个脚本时,它只是停留在终端上什么也不做。

仅运行此行代码:

paste <(tail -f "$FILE_1") <(tail -f "$FILE_2")

这个程序非常完美,我可以在终端上看到当我向文件中添加数据时的输出。

我需要使用特殊的语法才能将stdout导入到另一个进程吗?

我尝试过以下操作:

paste <(tail -f "$FILE_1") <(tail -f "$FILE_2") | while read LINE; do...

但它仍然只停留在终端。

@Kashyap 不,我正在尝试使用重定向进行进程替换。我不确定 << (...) 甚至是什么意思。 - user3473949
@Kashyap:我找不到使用 << 运算符的任何信息。你能给我提供相关手册页面的链接吗? - user3473949
4
@kashyap 在混淆这些文档,但这完全是个扯红线。删除这个评论线是一个良好的前进方式。 - tripleee
听起来像是缓冲。你检查过它是否只是在等待您向文件添加足够数量的行吗? - that other guy
@thatotherguy: 缓存到底是什么呢?它应该随着数据进来就从管道中读取,对吗?我相信只要有数据可用,读取就会解除阻塞。而且只要将粘贴命令与两个进程替换作为输入即可正常工作,那么我该如何获得stdout流呢? - user3473949
显示剩余2条评论
2个回答

6
当标准输出不是终端时,paste将缓冲其输出。你的命令有效,只是需要一定量的输入才会有任何反应。
要立即获得输出,您可以使用stdbuf取消缓冲stdout:
stdbuf -oL paste <(tail -f "$FILE_1") <(tail -f "$FILE_2") | while read LINE; do...

0

我相信你有两个主要问题。第一个问题是你需要结合使用here string命令替换进程替换来实现你想要的重定向。例如:

while read LINE
do 
    echo "$LINE"
done <<< "$( paste <( tail -2 "$FILE_1" ) <( tail -2 "$FILE_1" ) )"

上述命令可以正常工作。但是,请注意,上述命令使用了一个可确定的行集合,通过使用tail的封闭形式(例如tail -2)从FILE_1FILE_2中提取。我认为在这种情况下无法使用follow选项。我正在寻找原因,但尚未找到规则。使用--serial选项进行粘贴没有任何区别。


谢谢,我会考虑使用这些元素的组合。您能解释一下为什么我尝试的进程替换不起作用吗?只有将两个进程替换作为输入的粘贴命令可以正常工作,那么我该如何获取stdout流呢? - user3473949

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接