我今天在ubuntu 14.04下使用fifo使用awk命令和数据流时遇到了问题。
我有一个提供数据的writer.sh
#!/bin/bash
PIPE_NAME="pipe.fifo"
DATA="dataA,dataB"
# create fifo if doesn't exist
if ! [ -p "$PIPE_NAME" ]; then
mkfifo $PIPE_NAME
fi
# keep fifo openned
sleep 10000 > $PIPE_NAME &
while [[ true ]];
do
echo $DATA > $PIPE_NAME
sleep 1
done
工作正常。
在另一个shell上,如果我写命令:
cat pipe.fifo|grep data|awk -F, '{print $1}'
我没有得到任何东西。
我尝试使用以下内容创建dataList.txt文件:
dataA,dataB
dataA,dataB
dataA,dataB
以下命令:
cat dataList.txt|grep data|awk -F, '{print $1}'
产生预期结果:
dataA
dataA
dataA
注意:grep命令对此没有任何兴趣,但在我的应用程序中,仅获取与特定模式匹配的数据非常有用。
你知道我误解了什么吗?
答案 0 :(得分:1)
writer.sh
中对管道的第一次写入将阻塞,直到从管道中读取内容。我建议像这样写writer.sh
:
#!/bin/bash
pipe_name="pipe.fifo"
data="dataA,dataB"
[ -p "$pipe_name" ] || mkfifo "$pipe_name"
while :; do
echo "$data"
sleep 1
done > "$pipe_name"
此处,管道将保持打开状态,直到您的while
循环退出。
如果grep
正在缓冲其输出,那么它会在数据到达时连续从管道中读取,但它不会输出任何内容到管道awk
,直到缓冲区已满或直到它存在。由于writer.sh
处于无限循环中,因此您只需等待缓冲区已满。
由于grep | awk
的组合在某种程度上是反模式的(因为awk
可以自行过滤),您可以用
awk -F, '/data/ {print $1}' pipe.fifo
,因为它写入终端,不会缓冲其输出。