假设我在bash中有以下命令:
one | two
one
运行很长时间产生输出流,two
对该流的每一行执行快速操作,但two
根本不起作用,除非第一行它读取的值告诉它每行读取多少个值。 one
没有输出该值,但我事先知道它是什么(让我们说它是15
)。我想在15\n
的输出之前通过管道发送one
。我不想修改one
或two
。
我的第一个想法是:
echo "$(echo 15; one)" | two
这给了我正确的输出,但在命令one
完成之前它根本不会通过管道流。我希望输出通过管道立即开始流式传输,因为执行需要很长时间(几个月)。
我也尝试过:
echo 15; one | two
当然,输出15,但不会通过管道将其发送到two
。
在bash中是否有办法通过管道传递'15 \ n'然后开始通过同一个管道传输one
的输出?
答案 0 :(得分:13)
您只需要shell分组构造:
{ echo 15; one; } | two
大括号和尾随分号周围的空格是必需的。
测试:
one() { sleep 5; echo done; }
two() { while read line; do date "+%T - $line"; done; }
{ printf "%s\n" 1 2 3; one; } | two
16:29:53 - 1
16:29:53 - 2
16:29:53 - 3
16:29:58 - done
答案 1 :(得分:4)
答案 2 :(得分:2)
您可以使用sed执行此操作:
示例'one'脚本,每秒发出一行以显示其缓冲并运行的行。
#!/bin/bash
while [ 1 ]; do
echo "TICK $(date)"
sleep 1
done
然后通过此sed命令管道,请注意,对于您的特定示例'ArbitraryText'将是字段数。我使用了ArbitraryText,因此很明显这是插入的文本。在OSX上, -l </ strong>与GNU Sed无缓冲我相信它是 -u
$ ./one | sed -l '1i\
> ArbitraryText
> '
这样做是指示sed在处理文件的其余部分之前插入一行,其他所有内容都将不受影响。
最终结果是逐行处理的,没有块缓冲(或等待输入脚本完成)
ArbitraryText
TICK Fri Jun 28 13:26:56 PDT 2013
...etc
你应该能够像往常那样将它传递给'两个'。