Shell脚本中从标准输入管道取得数据
需求
前两年写过一个webhook《Telegram机器人开发初步——一个Grafana告警机器人》,但是那个只能传入简单的字符串组成的JSON参数。
这回的问题是,我需要把一个脚本执行的结果——通过标准输出的大段日志内容通过这个webhook发送给tg机器人。常规的方法是这样:
source.sh | send_to_tgbot.sh
其中的send_to_tgbot.sh是类似这样的:
curl -XPOST -d "{\"message\": \"$1\"}" https://yourdomain/tgbot_xxx
这样显然是无法实现所需要的功能的。
解决
首先是要读取通过管道进来的标准输入的内容到参数中,最简单的方法就是把它cat到变量里:
MSG=$(cat)
curl -XPOST -d "{\"message\": \"$MSG\"}" https://yourdomain/tgbot_xxx
但是这样直接把这个变量放到JSON里会有问题,因为其中会有很多控制字符会破坏JSON的结构,需要转义一下:
MSG=$(printf "%q" "$(cat)")
但这样转义以后就会给结果字符串加上:$'',还得用sed去掉一下,顺便再给双引号也加上转义:
MSG=$(printf "%q" "$(cat)" | sed 's/^$'\''//; s/'\''$//; s/\"/\\"/g')
最后给参数加上选项-,指定使用标准输入,否则仍然按原来传参方式使用:
MSG=$1
if [ "$MSG" = "-" ]
then
MSG=$(printf "%q" "$(cat)" | sed 's/^$'\''//; s/'\''$//; s/\"/\\"/g')
fi
推送到[go4pro.org]