我正在编写一个 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===
.