Shell脚本如何配置飞书消息推送:从零到实战的完整指南
目录导读
-
为什么要用Shell脚本推送飞书消息?

-
前置准备:获取飞书机器人Webhook地址
-
基础配置:使用curl发送消息
-
高级技巧:格式化消息与变量传递
-
实战案例:定时任务监控服务器状态
-
常见问题与解决方案(Q&A)
为什么要用Shell脚本推送飞书消息?
在运维和开发工作中,我们经常需要实时获取服务器状态、部署结果或异常告警,飞书作为企业协作工具,通过机器人Webhook接口,可以快速将消息推送到群聊或用户。
核心场景包括:
- 服务器CPU/内存/磁盘告警
- 自动化部署成功/失败通知
- 定时任务执行结果反馈
- 日志异常实时监控
使用Shell脚本配置飞书消息推送,无需额外安装SDK,仅依赖Linux内置的curl命令即可实现,轻量、高效、可移植性强。
前置准备:获取飞书机器人Webhook地址
1 创建飞书群组机器人
- 打开飞书桌面端或移动端,进入目标群聊(或创建新群)
- 点击群设置 → 群机器人 → 添加机器人 → 选择“自定义机器人”
- 设置机器人名称和头像(可选),点击“完成”
- 复制生成的Webhook地址,格式如下:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2 安全提醒
- Webhook地址包含鉴权信息,请勿泄露到公开代码库
- 可在飞书机器人设置页面开启“IP白名单”或“签名校验”(推荐)
基础配置:使用curl发送消息
1 最简单的推送脚本
#!/bin/bash
# 定义Webhook地址变量
WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/你的Webhook地址"
# 定义消息内容(JSON格式)
MESSAGE='{
"msg_type": "text",
"content": {
"text": "这是一条来自Shell脚本的测试消息"
}
}'
# 使用curl发送POST请求
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK_URL"
执行方法:
chmod +x send_feishu.sh ./send_feishu.sh
2 支持中文与特殊字符
飞书API要求消息内容为UTF-8编码,使用$MESSAGE变量时建议用单引号包裹JSON,避免Shell解析字符,若需动态拼接,可用双引号并转义。
高级技巧:格式化消息与变量传递
1 使用Markdown增强可读性
飞书支持post(富文本)和interactive(卡片消息)格式,下面展示最常用的Markdown格式:
#!/bin/bash
WEBHOOK_URL="你的Webhook地址"
# 定义时间变量
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
# 构建Markdown消息
CONTENT="**服务器状态报告**\n时间:${CURRENT_TIME}\n---\n- 主机名:\`$(hostname)\`\n- 磁盘使用率:$(df -h / | tail -1 | awk '{print $5}')"
MESSAGE=$(cat <<EOF
{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "系统告警通知"}
},
"elements": [
{
"tag": "markdown",
"content": "${CONTENT}"
}
]
}
}
EOF
)
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK_URL"
说明:
interactive类型支持卡片样式,header,elementsmarkdown标签支持标准Markdown语法,如**粗体**、- 无序列表、代码块``- 变量通过
${CONTENT}注入,注意JSON内不要出现未转义的双引号
2 传递函数参数
若脚本需要被多次调用,可将Webhook地址和消息作为参数传入:
#!/bin/bash
send_to_feishu() {
local webhook="$1"
local msg="$2"
local payload=$(cat <<EOF
{
"msg_type": "text",
"content": {"text": "$msg"}
}
EOF
)
curl -X POST -H "Content-Type: application/json" -d "$payload" "$webhook"
}
# 调用示例
send_to_feishu "https://open.feishu.cn/open-apis/bot/v2/hook/xxx" "任务执行完成"
实战案例:定时任务监控服务器状态
1 编写监控脚本(monitor.sh)
#!/bin/bash
WEBHOOK="你的Webhook地址"
# 定义阈值
CPU_THRESHOLD=80 # CPU使用率>80%告警
MEM_THRESHOLD=90 # 内存使用率>90%告警
DISK_THRESHOLD=85 # 磁盘使用率>85%告警
# 获取系统指标
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
MEM_USAGE=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
# 判断是否告警
ALERT_MSG=""
if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
ALERT_MSG+="⚠️ **CPU告警**:当前使用率 ${CPU_USAGE}%(阈值 ${CPU_THRESHOLD}%)\n"
fi
if (( $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc -l) )); then
ALERT_MSG+="⚠️ **内存告警**:当前使用率 ${MEM_USAGE}%(阈值 ${MEM_THRESHOLD}%)\n"
fi
if (( "$DISK_USAGE" > "$DISK_THRESHOLD" )); then
ALERT_MSG+="⚠️ **磁盘告警**:当前使用率 ${DISK_USAGE}%(阈值 ${DISK_THRESHOLD}%)\n"
fi
# 若有告警则推送
if [ -n "$ALERT_MSG" ]; then
CONTENT="**服务器异常通知**\n服务器:$(hostname)\n时间:$(date '+%Y-%m-%d %H:%M:%S')\n\n${ALERT_MSG}"
MESSAGE=$(cat <<EOF
{
"msg_type": "interactive",
"card": {
"header": {"title": {"tag": "plain_text", "content": "🚨 服务器告警"}},
"elements": [{"tag": "markdown", "content": "${CONTENT}"}]
}
}
EOF
)
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK"
fi
2 添加定时任务
使用crontab每5分钟执行一次:
crontab -e # 添加以下行(注意使用绝对路径) */5 * * * * /path/to/monitor.sh
说明:
- 脚本中使用了
bc进行浮点数比较,需确保系统已安装bc(通过yum install bc或apt install bc) df /监控根分区,可根据实际挂载点调整
常见问题与解决方案(Q&A)
Q1:消息发送失败,返回400错误?
A: 通常是因为Webhook地址错误或JSON格式不正确,解决方案:
- 检查
curl -v输出,确认响应体中的errmsg字段 - 使用在线JSON验证工具检查消息格式
- 确保
msg_type字段正确("text","post","interactive"之一)
Q2:如何发送@某人的消息?
A: 使用interactive卡片消息时,在content中加入@user_id,注意飞书API要求传入用户ID(非手机号):
"content": "@{user_id_xxxx} 请查看告警信息"
Q3:Shell脚本中变量包含空格或特殊字符怎么办?
A: 使用双引号包裹变量,并对特殊字符进行转义:
# 错误示例(变量含空格会被拆分为多个参数)
MESSAGE='{"text":"'$VAR'"}'
# 正确做法:使用printf或jq工具
MESSAGE=$(printf '{"msg_type":"text","content":{"text":"%s"}}' "$VAR")
推荐安装jq工具进行JSON构建(yum install jq):
MESSAGE=$(jq -n --arg msg "$VAR" '{msg_type:"text", content: {text: $msg}}')
Q4:如何实现发送后自动重试?
A: 在curl命令后添加清理逻辑,失败时重试一定次数:
MAX_RETRIES=3
for i in $(seq 1 $MAX_RETRIES); do
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$WEBHOOK")
if [ "$RESPONSE" -eq 200 ]; then
echo "发送成功"
break
else
echo "发送失败,重试第${i}次"
sleep 2
fi
done
Q5:脚本可以同时推送多个群组吗?
A: 可以,定义多个Webhook数组,遍历发送:
WEBHOOKS=("url1" "url2" "url3")
for url in "${WEBHOOKS[@]}"; do
curl -X POST -H "Content-Type: application/json" -d "$MESSAGE" "$url"
done
通过Shell脚本配置飞书消息推送,是自动化运维中成本最低、最灵活的方案之一,从简单的文本通知到复杂的卡片告警,只需清楚JSON格式化要点和飞书API接口规范,推荐结合crontab、Prometheus告警回调或Jenkins构建后任务,实现全流程自动化。
延伸学习:
- 飞书开放平台官方文档:open.feishu.cn(搜索“自定义机器人”)
- 进阶技巧:使用飞书签名校验(HMAC-SHA1)提高安全性
- 配合
jq、yq等工具处理复杂JSON结构
注意: 实际生产环境中,建议将敏感信息(如Webhook地址)通过环境变量或密钥管理服务存储,而非硬编码在脚本中。