如何将tail -f输出通过管道传入shell脚本实现Telegram日志推送
问题原因分析
tail -f属于持续输出模式,对应输入流不会主动终止,你脚本中的TEXT=$(tee)需要等待输入流完全结束才会读取所有内容完成变量赋值,因此脚本会永久卡在这一步,永远不会执行后续的curl请求。- 你直接将日志内容拼接在curl的-d参数中,没有做URL编码处理,日志里的特殊字符(换行、&、%、+、空格等)会破坏POST参数结构,导致请求发送失败或者内容解析异常。
修复方案
可以调整为逐行读取管道输入的日志,每收到一行新日志就触发一次推送,同时新增URL编码逻辑适配参数规则。
修正后的脚本代码
#!/bin/bash CHATID="替换为你的实际chat id" KEY="替换为你的实际bot key" TIME="10" URL="https://api.telegram.org/bot$KEY/sendMessage" # URL编码处理函数 urlencode() { local str="$*" local len=${#str} local encoded="" local pos c o for (( pos=0 ; pos<len ; pos++ )); do c=${str:$pos:1} case "$c" in [a-zA-Z0-9.~_-]) encoded+="$c" ;; *) printf -v o '%%%02X' "'$c" encoded+="$o" ;; esac done echo "$encoded" } # 逐行读取管道输入的日志 while IFS= read -r line; do encoded_text=$(urlencode "$line") curl -s --max-time $TIME -d "chat_id=$CHATID&disable_web_page_preview=1&text=$encoded_text" "$URL" >/dev/null done
使用步骤
- 替换脚本中
CHATID和KEY为你自己的实际参数 - 给脚本添加执行权限:
chmod +x telegram_log.sh - 执行原命令即可正常推送新产生的日志:
tail -f /var/log/my.log | ./telegram_log.sh
如果需要批量推送历史日志,去掉tail命令的-f参数即可一次性逐行推送所有日志内容。
内容的提问来源于stack exchange,提问作者Xenro
相关产品推荐
相关产品推荐

