I have a program that output some text and then a continuous stream of characters:
perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10'
I want to exit this program as soon as "A" is seen in the output and I tried:
我想在输出中看到“A”后就退出这个程序,我尝试:
grep -m 1 A <(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10')
However, it seems like grep doesn't see the "A"s until the perl program exits.
然而,grep似乎直到perl程序退出才看到“A”。
I also tried with sed with no luck;
我也尝试过sed,但是没有成功;
sed /A/q <(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10')
Any ideas how I can solve this?
有什么办法解决这个问题吗?
1 个解决方案
#1
2
The issue here is that both grep
and sed
process their input linewise unless they are told otherwise. One workaround is to insert newlines, e.g. with coreutils fold
:
这里的问题是,grep和sed都以线性方式处理它们的输入,除非被告知不这样做。一种方法是插入换行,例如用coreutils折叠:
grep -m 1 A \
<(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' | fold -w1)
But this still has issues because of pipe-buffering. You can disable this with coreutils stdbuf
:
但由于管道缓冲,这仍然存在问题。你可以禁用coreutils stdbuf:
grep -m 1 A \
<(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' |
stdbuf -o0 fold -w1)
Another alternative is to use dd
, e.g.:
另一种选择是使用dd,例如:
perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' |
while :; do
c=$(dd bs=1 count=1 status=none)
if [[ "$c" == "A" ]]; then
break
else
: Do something else
fi
done
#1
2
The issue here is that both grep
and sed
process their input linewise unless they are told otherwise. One workaround is to insert newlines, e.g. with coreutils fold
:
这里的问题是,grep和sed都以线性方式处理它们的输入,除非被告知不这样做。一种方法是插入换行,例如用coreutils折叠:
grep -m 1 A \
<(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' | fold -w1)
But this still has issues because of pipe-buffering. You can disable this with coreutils stdbuf
:
但由于管道缓冲,这仍然存在问题。你可以禁用coreutils stdbuf:
grep -m 1 A \
<(perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' |
stdbuf -o0 fold -w1)
Another alternative is to use dd
, e.g.:
另一种选择是使用dd,例如:
perl -E '$|=1;print "OUT\n";print "A" and sleep 1 for 1..10' |
while :; do
c=$(dd bs=1 count=1 status=none)
if [[ "$c" == "A" ]]; then
break
else
: Do something else
fi
done