一、目的與演示效果
解析服務端返回的如下字符串,獲取今日數(shù)據(jù)、歷史數(shù)據(jù),實現(xiàn)釘釘定時推送戰(zhàn)報效果。
{
"code": "00000",
"msg": "",
"success": true,
"data": {
"2023-07-19": [
"1673945805117063168",
"1671561317942689792",
"1658787124574552064",
"1675750158471659520"
],
"2023-07-20": [
"1673945805117063168",
"1671561317942689792",
"1658787124574552064",
"1675750158471659520"
]
},
"ref": null
}

二、請求網(wǎng)絡(luò)
1、curl獲取數(shù)據(jù)并賦值變量
在shell中直接使用curl http://www.baidu.com會出現(xiàn)下載器,因此我們拼接一個-s
。
對于接收數(shù)據(jù)的變量api_result:其后面的等號前后都不要有空格。
對于要執(zhí)行的函數(shù):用反單引號包裹起來
api_result=`curl -s http://www.baidu.com`
也可以使用eval函數(shù)來執(zhí)行。以下為等價寫法:
api_result=`eval 'curl -s http://www.baidu.com'`
2、帶參數(shù)
對于整個地址用引號(單、雙都可)拼接起來,要不然不識別拼接的參數(shù)。示例:
api_result=`eval 'curl -s "http://www.baidu.com?s=1&c=ANDROID"'`
等價eval寫法:
api_result=`curl -s 'http://www.baidu.com?s=1&c=ANDROID'`
3、封裝網(wǎng)絡(luò)請求方法
對于請求網(wǎng)絡(luò),往往是為了拿到里層的data數(shù)據(jù)。因此可以考慮封裝方法來復用。這里含有以下知識點:
1、方法參數(shù)傳遞使用$1 $2 $3等,代表第一個參數(shù)、第二個參數(shù)的意思。
調(diào)用的時候把參數(shù)放方法后面,中間以空格連接即可。
2、echo為返回,不要用return,return只能返回數(shù)字類型。
#!/bin/bash
# 請求網(wǎng)絡(luò),拿到里層data數(shù)據(jù)
# {"code":"00000","msg":"","success":true,"data":{"2023-07-12":["1679009176166203392"]},"ref":null}
checkUploadResult(){
api_result=`eval $1` # 執(zhí)行api_result,拿到返回的結(jié)果
data=$(echo $api_result | jq -r '.data')
echo $data
}
# 調(diào)用方法
androidTotalTodo=`checkUploadResult "curl -s 'http:/www.baidu.com?s=1&c=ANDROID'"`
三、json解析
shell的json解析,這里以jq解析為主,以封裝的getJsonValuesByAwk解析為輔。主要是jq解析獲取key的時候要求key不能是數(shù)字
1、根據(jù)key獲取value (key非數(shù)字)
【key非數(shù)字】從json數(shù)據(jù)api_result中取data,即可這樣寫
api_result='{"code":"00000","msg":"","success":true,"data":{"2023-07-12":["1679009176166203392"]},"ref":null}'
data=$(echo $api_result | jq -r '.data')
echo $data
# 打印數(shù)據(jù):{ "2023-07-12": [ "1679009176166203392" ] }
【key為數(shù)字】這個時候使用jq解析會報錯
json='{"2023-07-12":["1679009176166203392"],"2023-07-13":["1679009176166203392"]}'
data=$(echo $json | jq -r '.2023-07-12')
echo $data
# 打印數(shù)據(jù):-18.7977
然后我們使用getJsonValuesByAwk解析就正常了
### 方法簡要說明:
### 1. 是先查找一個字符串:帶雙引號的key。如果沒找到,則直接返回defaultValue。
### 2. 查找最近的冒號,找到后認為值的部分開始了,直到在層數(shù)上等于0時找到這3個字符:,}]。
### 3. 如果有多個同名key,則依次全部打?。ú徽搶蛹墸话闯霈F(xiàn)順序)
### @author lux feary
###
### 3 params: json, key, defaultValue
function getJsonValuesByAwk() {
awk -v json="$1" -v key="$2" -v defaultValue="$3" 'BEGIN{
foundKeyCount = 0
while (length(json) > 0) {
# pos = index(json, "\""key"\""); ## 這行更快一些,但是如果有value是字符串,且剛好與要查找的key相同,會被誤認為是key而導致值獲取錯誤
pos = match(json, "\""key"\"[ \\t]*?:[ \\t]*");
if (pos == 0) {if (foundKeyCount == 0) {print defaultValue;} exit 0;}
++foundKeyCount;
start = 0; stop = 0; layer = 0;
for (i = pos + length(key) + 1; i <= length(json); ++i) {
lastChar = substr(json, i - 1, 1)
currChar = substr(json, i, 1)
if (start <= 0) {
if (lastChar == ":") {
start = currChar == " " ? i + 1: i;
if (currChar == "{" || currChar == "[") {
layer = 1;
}
}
} else {
if (currChar == "{" || currChar == "[") {
++layer;
}
if (currChar == "}" || currChar == "]") {
--layer;
}
if ((currChar == "," || currChar == "}" || currChar == "]") && layer <= 0) {
stop = currChar == "," ? i : i + 1 + layer;
break;
}
}
}
if (start <= 0 || stop <= 0 || start > length(json) || stop > length(json) || start >= stop) {
if (foundKeyCount == 0) {print defaultValue;} exit 0;
} else {
print substr(json, start, stop - start);
}
json = substr(json, stop + 1, length(json) - stop)
}
}'
}
json='{"2023-07-12":["1679009176166203392"],"2023-07-13":["1679009176166203392"]}'
data=`getJsonValuesByAwk "$json" '2023-07-12' '沒有數(shù)據(jù)'`
echo $data
# 打印數(shù)據(jù):["1679009176166203392"]
2、獲取數(shù)組長度
list='["1679009176166203392"]'
arr=($(echo $list | tr -d '[],'))
echo "${#arr[@]}"
# 打印數(shù)據(jù):1
3、刪除json中的某個key
json='{"2023-07-12":["1679009176166203392"],"2023-07-13":["1679009176166203392"]}'
json=$(echo "$json" | jq 'del(.["2023-07-12"])')
echo "$json"
# 打印數(shù)據(jù):
#{
# "2023-07-13": [
# "1679009176166203392"
# ]
#}
4、刪除空格與引號
釘釘要求文案中不能有空格與引號,否則推送報錯。
# 刪除空格
dingtalkResult="${dingtalkResult// /}"
# 刪除引號"
dingtalkResult=${dingtalkResult//"\""/}
5、判斷數(shù)據(jù)是否為空
比如對未聲明的變量json。前面判斷是否是字符串null,后邊"-z"選項來檢查變量是否為空。
#!/bin/bash
# null字符串或者空
if [ "$json" = "null" ] || [ -z "$json" ]; then
echo '數(shù)據(jù)空'
else
echo '數(shù)據(jù)不空'
fi
# 打印數(shù)據(jù):數(shù)據(jù)空
四、釘釘推送
提供兩種,一種是帶At一種不帶
# 釘釘通知
notifyDingTalk(){
curl "https://oapi.dingtalk.com/robot/send?access_token=$DKEY" \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "'$1'"
},
}'
}
# 釘釘通知帶at
notifyDingTalkWithAt(){
curl "https://oapi.dingtalk.com/robot/send?access_token=$DKEY" \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "'$1'"
},
"at": {
"atMobiles": [
"1875819063x",
"1580366544x"
],
"isAtAll": false
}
}'
}
使用如下
notifyDingTalk '這是發(fā)給釘釘?shù)奈陌?
notifyDingTalkWithAt '這是發(fā)給釘釘?shù)奈陌?
配置安全文案即可

五、jenkins配置
jenkins配置定時器如下
H 17 * * *
會提示構(gòu)建時間文章來源:http://www.zghlxwxcb.cn/news/detail-602112.html

六、源碼
敏感信息部分以xxx打碼,替換自己的后不影響運行。文章來源地址http://www.zghlxwxcb.cn/news/detail-602112.html
#!/bin/bash
# 工作臺視頻上傳定時任務
# 當前時間(示例:2023-07-15)
cur_time=`date +"%F"`
#釘釘key
DKEY="65f276f7747278212d5fb85729117037bb62485b7573eb6b1ba028acf2ef6fxx"
# 默認為null字符串
emptyValue=null
# 檢測是否是定時任務觸發(fā)的構(gòu)建
# 如果 $toDingTalk 為空,則默認發(fā)送釘釘消息
if [ -z "$toDingTalk" ]; then
toDingTalk=true
fi
### 方法簡要說明:
### 1. 是先查找一個字符串:帶雙引號的key。如果沒找到,則直接返回defaultValue。
### 2. 查找最近的冒號,找到后認為值的部分開始了,直到在層數(shù)上等于0時找到這3個字符:,}]。
### 3. 如果有多個同名key,則依次全部打?。ú徽搶蛹墸话闯霈F(xiàn)順序)
### @author lux feary
###
### 3 params: json, key, defaultValue
function getJsonValuesByAwk() {
awk -v json="$1" -v key="$2" -v defaultValue="$3" 'BEGIN{
foundKeyCount = 0
while (length(json) > 0) {
# pos = index(json, "\""key"\""); ## 這行更快一些,但是如果有value是字符串,且剛好與要查找的key相同,會被誤認為是key而導致值獲取錯誤
pos = match(json, "\""key"\"[ \\t]*?:[ \\t]*");
if (pos == 0) {if (foundKeyCount == 0) {print defaultValue;} exit 0;}
++foundKeyCount;
start = 0; stop = 0; layer = 0;
for (i = pos + length(key) + 1; i <= length(json); ++i) {
lastChar = substr(json, i - 1, 1)
currChar = substr(json, i, 1)
if (start <= 0) {
if (lastChar == ":") {
start = currChar == " " ? i + 1: i;
if (currChar == "{" || currChar == "[") {
layer = 1;
}
}
} else {
if (currChar == "{" || currChar == "[") {
++layer;
}
if (currChar == "}" || currChar == "]") {
--layer;
}
if ((currChar == "," || currChar == "}" || currChar == "]") && layer <= 0) {
stop = currChar == "," ? i : i + 1 + layer;
break;
}
}
}
if (start <= 0 || stop <= 0 || start > length(json) || stop > length(json) || start >= stop) {
if (foundKeyCount == 0) {print defaultValue;} exit 0;
} else {
print substr(json, start, stop - start);
}
json = substr(json, stop + 1, length(json) - stop)
}
}'
}
# 請求網(wǎng)絡(luò),拿到里層data數(shù)據(jù)
# {"code":"00000","msg":"","success":true,"data":{"2023-07-12":["1679009176166203392","1676130723649683456","1675059618608447488","1674345317023219712","1672586086360154112","1673586172305211392","1673950865947492352","1675757864595095552","1670766831293562880","1674976668499968000","1676513810044813312","1676512377715163136","1675146378722017280","1673687264389103616","1675283959501684736","1674213349681922048","1675545501522591744","1674269196629966848","1669551312678813696","1675366041963855872","1675445816296341504","1668133451263508480","1673610261883387904","1673945805117063168","1671561317942689792","1658787124574552064","1675750158471659520"]},"ref":null}
checkUploadResult(){
api_result=`eval $1` # 執(zhí)行cmd,拿到返回的結(jié)果
data=$(echo $api_result | jq -r '.data')
echo $data
}
# 獲取今天的數(shù)據(jù)
getTodayList(){
json=`getJsonValuesByAwk "$1" $cur_time $emptyValue`
echo $json
}
getArrayLengthFromString(){
# null或者null字符串
if [ "$1" = "null" ] || [ -z "$1" ]; then
echo 0
else
arr=($(echo "$1" | tr -d '[],'))
echo "${#arr[@]}"
fi
}
# 刪除今日數(shù)據(jù)
deleteTodayData(){
# null或者null字符串
if [ "$1" = "null" ] || [ -z "$1" ]; then
echo {}
else
# 轉(zhuǎn)正常json
# 使用 jq 命令將 JSON 字符串變量轉(zhuǎn)換為 JSON 變量
# json=$(echo "$1" | jq .)
# 刪除今日數(shù)據(jù)
json=$(echo "$1" | jq 'del(.["'$cur_time'"])')
echo "$json"
fi
}
# 總計
androidTotalTodo=`checkUploadResult "curl -s 'https://pre-api.xx.com/na/api/manual/v2/getVideoInfo?s=1&c=ANDROID'"`
androidTotalFinish=`checkUploadResult "curl -s 'https://pre-api.xx.com/na/api/manual/v2/getVideoInfo?s=2&c=ANDROID'"`
# 今日
androidTodayTodo=`getTodayList "$androidTotalTodo"`
androidTodayFinish=`getTodayList "$androidTotalFinish"`
# 總計
iosTotalListTodo=`checkUploadResult "curl -s 'https://pre-api.xx.com/na/api/manual/v2/getVideoInfo?s=1&c=IOS'"`
iosTotalListFinish=`checkUploadResult "curl -s 'https://pre-api.xx.com/na/api/manual/v2/getVideoInfo?s=2&c=IOS'"`
# 今日
iosTodayTodo=`getTodayList "$iosTotalListTodo"`
iosTodayFinish=`getTodayList "$iosTotalListFinish"`
# 總共未完成
totalTodo=`checkUploadResult "curl -s 'https://pre-api.xx.com/na/api/manual/v2/getVideoInfo?s=1'"`
dingtalkResult+="\n一、今日待上傳"
dingtalkResult+="\n1、安卓今日待上傳:【"`getArrayLengthFromString "$androidTodayTodo"`"個】\n"$androidTodayTodo
dingtalkResult+="\n2、ios今日待上傳:【"`getArrayLengthFromString "$iosTodayTodo"`"個】\n"$iosTodayTodo
dingtalkResult+="\n\n二、今日完成"
dingtalkResult+="\n1、安卓完成上傳:【"`getArrayLengthFromString "$androidTodayFinish"`"個】"
dingtalkResult+="\n2、ios完成上傳:【"`getArrayLengthFromString "$iosTodayFinish"`"個】"
dingtalkResult+="\n\n三、歷史待上傳"
androidTotalTodo=$(deleteTodayData "$androidTotalTodo")
iosTotalListTodo=$(deleteTodayData "$iosTotalListTodo")
totalTodo=$(deleteTodayData "$totalTodo")
# 使用 jq 命令將 JSON 對象轉(zhuǎn)換為字符串
sum_totalTodo=$(echo "$totalTodo" | jq -c .)
# 判斷整數(shù)值是否為 0
if [ "${#sum_totalTodo}" -eq 0 ]; then
dingtalkResult+="\n{}"
else
dingtalkResult+="\n"$sum_totalTodo
fi
# 刪除空格
dingtalkResult="${dingtalkResult// /}"
# 刪除引號"
dingtalkResult=${dingtalkResult//"\""/}
# 釘釘通知
notifyDingTalk(){
if [ $toDingTalk == true ]; then
echo $1
curl -s "https://oapi.dingtalk.com/robot/send?access_token=$DKEY" \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "'$1'"
},
}'
else
echo $1
fi
}
# 釘釘通知帶at
notifyDingTalkWithAt(){
if [ $toDingTalk == true ]; then
echo $1
curl -s "https://oapi.dingtalk.com/robot/send?access_token=$DKEY" \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "'$1'"
},
"at": {
"atMobiles": [
"187581906xx",
"158036654xx"
],
"isAtAll": false
}
}'
else
echo $1
fi
}
if test "$androidTodayTodo" != null && test "$iosTodayTodo" != null; then
notifyDingTalk "【"$cur_time"】今天andriod、ios視頻都未上傳完!以下是具體數(shù)據(jù):${dingtalkResult}"
elif test "$androidTodayTodo" != null; then
notifyDingTalk "【"$cur_time"】今天andriod視頻未上傳完!以下是具體數(shù)據(jù):${dingtalkResult}"
elif test "$iosTodayTodo" != null; then
notifyDingTalk "【"$cur_time"】今天ios視頻未上傳完!以下是具體數(shù)據(jù):${dingtalkResult}"
else
notifyDingTalk "【"$cur_time"】今日視頻上傳完畢!辛苦了!${dingtalkResult}"
fi
到了這里,關(guān)于shell腳本定時推送釘釘戰(zhàn)報的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!