![通过管道将 demo 输出传递给函数](https://linux22.com/image/89997/%E9%80%9A%E8%BF%87%E7%AE%A1%E9%81%93%E5%B0%86%20demo%20%E8%BE%93%E5%87%BA%E4%BC%A0%E9%80%92%E7%BB%99%E5%87%BD%E6%95%B0.png)
我收到一条带有 mosquitto_sub 的 MQTT 消息,我想将输出(两个字符串)重定向到一个函数。
客户:
mosquitto_pub -d -t hello/world/ -m "Alessio,base64"
在服务器上我有一个 bash 程序
服务器:(有效)
function pipeTee(){
tee -a mqtt_broker.log
}
mosquitto_sub -t +/# | pipeTee
但如果我也尝试通过管道连接到另一个函数,该程序将无法工作。
#!/bin/bash
function testPipe(){
echo "va"
}
function pipeTee(){
tee -a mqtt_broker.log
}
mosquitto_sub -t +/# | pipeTee | testPipe
来自客户端的 mosquitto_pub:
mosquitto_pub -d -t hello/world -m "Aless,base64"
Client mosqpub/1841-raspberryp sending CONNECT
Client mosqpub/1841-raspberryp received CONNACK
Client mosqpub/1841-raspberryp sending PUBLISH (d0, q0, r0, m1, 'hello/world', ... (12 bytes))
Client mosqpub/1841-raspberryp sending DISCONNECT
服务器不工作时:
pi@raspberrypi:~ $ ./mqtt_broker.sh
va
^C
并且文件日志为空
答案1
考虑以下 shell 脚本:
function thetee {
tee data.out
}
function thepipe {
echo "Hello!"
}
while true; do
echo "Hi there!"
done | thetee | thepipe
echo "Done."
这里的-loopwhile
是一个无限行的生成器,其中包含文本“Hi There!”。
运行它:
$ sh script.sh
Hello!
Done.
然后查看 中的行数data.out
:
$ wc -l data.out
274 data.out
再次:
$ sh script.sh
Hello!
Done.
$ wc -l data.out
236 data.out
问题:
- 无限循环并不是无限的。
- 运行之间的输出行数不同。
理由:
我的示例中的函数
thepipe
只是回显一个字符串,然后退出,导致管道失败。管道的最后阶段无法处理进一步的输入,并且循环退出。实际写入的行数
data.out
取决于 shell 启动管道的速度以及函数thepipe
执行操作和退出的速度。
在您的情况下,这种情况发生得如此之快,以至于数据生成器 ( mosquitto_sub
) 的任何输入都无法到达该tee
函数。
解决方案:
实际制作thepipe
函数消耗其输入:
function thepipe {
echo "Hello!"
cat
}
这将使我的示例中的代码输出一个“Hello!”接下来是无限的“嗨,那里!” (也保存到data.out
)。echo
最后的永远不会被执行。
所以:
testPipe
以类似的方式更改函数的定义。例如:
function testPipe(){
echo "va"
cat
}
这将产生消耗输入并将其发送到管道的下一个阶段的效果,或者,如果它位于管道的末尾,则发送到标准输出在其之后重定向的任何位置(其中包含包含字符串的行va
)流的开始)。