Bash 管道停止工作

Bash 管道停止工作

我正在编写一个 bash 脚本来处理 mosquitto_sub 调用的输出:

function testPipe(){
 read foo
 IFS=' ' read -ra ARRAY <<< "$foo"
 topic=${ARRAY[0]}
 cmd=${ARRAY[1]}
 echo "topic = $topic cmd = $cmd"
 cat
}

function pipeTee(){
 tee -a mqtt_broker.log
}

mosquitto_sub -h $HOST -p $PORT -t $TOPIC \
      -u $USER -P $PASS -v | pipeTee | testPipe

我试图跟随通过管道将 demo 输出传递给函数。然而,这是我观察到的,第一条消息通过网络到达,函数 testPipe 被调用,我看到了解析的行。所有后续消息都会以原始方式打印到控制台,即它们来自网络。

我可能做错了什么? “read foo”不消耗 STDIN 中的输入吗?

答案1

如果您启动代理(使用mosquitto),则使用 订阅my/test主题

mosquitto_sub -t my/test -v

然后您可以发布简单的消息并查看您将收到什么。例如,

mosquitto_pub -t my/test -m inline

将在订阅输出中显示为单行

my/test inline

如果您的所有消息都是这种类型,您应该简单地执行一个循环来调用您的函数:

... | pipeTee | while testPipe; do : ; done

但你的函数不能使用cat,否则它永远不会返回。如果要发送多行消息,则需要将 替换cat为另一个 while 循环中的读取,该循环以某种方式检测消息的结尾。例如,如果您发布

echo -e 'my multi\nline test' | mosquitto_pub -t my/test -s

你会看到3行:

my/test my multi
line test
<there is a blank line here>

空行是因为在字符串中echo添加了一个。\n然后你需要cat用类似的东西替换

while read data && [ "$data" != "" ]
do    echo "Got $data"
done

由于您控制发布的内容,因此您可能更喜欢发送单行数据,或者以您可以轻松查找的特殊字符串结束消息,例如===eof===.

相关内容