通过管道将 demo 输出传递给函数

通过管道将 demo 输出传递给函数

我收到一条带有 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

问题:

  1. 无限循环并不是无限的。
  2. 运行之间的输出行数不同。

理由:

  1. 我的示例中的函数thepipe只是回显一个字符串,然后退出,导致管道失败。管道的最后阶段无法处理进一步的输入,并且循环退出。

  2. 实际写入的行数data.out取决于 shell 启动管道的速度以及函数thepipe执行操作和退出的速度。

在您的情况下,这种情况发生得如此之快,以至于数据生成器 ( mosquitto_sub) 的任何输入都无法到达该tee函数。

解决方案:

实际制作thepipe函数消耗其输入:

function thepipe {
    echo "Hello!"
    cat
}

这将使我的示例中的代码输出一个“Hello!”接下来是无限的“嗨,那里!” (也保存到data.out)。echo最后的永远不会被执行。

所以:

testPipe以类似的方式更改函数的定义。例如:

function testPipe(){
        echo "va"
        cat
}

这将产生消耗输入并将其发送到管道的下一个阶段的效果,或者,如果它位于管道的末尾,则发送到标准输出在其之后重定向的任何位置(其中包含包含字符串的行va)流的开始)。

相关内容