如何获取PostgreSQL无匹配行的退出码及Bacula脚本调整求助
解决Bacula作业筛选脚本的无匹配行判断问题
问题核心
你的脚本当前存在两个关键问题:
- PostgreSQL的
psql客户端执行SELECT语句时,即使无匹配行也会返回退出码0(仅SQL语法错误、连接失败等场景才会返回非0),导致无匹配行的结果错误写入jobscompleted.txt - 无匹配行时
psql会输出(0 rows),干扰后续逻辑判断
解决方案
通过优化psql参数和脚本逻辑,实现正确的结果分流:
1. 优化psql输出格式
使用-A -t参数消除冗余输出:
-A(--no-align):取消列对齐的空格,输出更简洁-t(--tuples-only):仅返回数据行,无匹配时输出为空,不再出现(0 rows)
2. 修正脚本判断逻辑
- 将
retVal=$?移至psql命令执行后,正确获取命令退出码 - 结合退出码和输出内容是否为空双重判断:只有当
psql执行成功且有返回数据时,才写入jobscompleted.txt,否则写入jobsnotcompleted.txt
修改后的完整脚本
rm -rf jobsfailed.txt jobscompleted.txt jobsnotcompleted.txt ## 清理旧文件 export PGPASSWORD="$PG_PASS" # 提取过去24小时内失败的作业 psql -A -t -U bacula bacula << EOD > jobsfailed.txt SELECT jobid,job,name,jobbytes,realendtime,jobstatus,level FROM job WHERE jobstatus IN ('f','A','E') AND realendtime > NOW() - INTERVAL '24 HOURS'; EOD # 获取去重后的作业名称列表 sortedlist=$(awk -F'|' '{print $3}' jobsfailed.txt | sort | uniq) for i in $sortedlist do # 查询该作业过去24小时内是否有成功或运行中的记录 jobs_notcompleted=$(psql -A -t -U bacula bacula << EOD1 SELECT jobid,job,name,jobbytes,realendtime,jobstatus,level FROM job WHERE name LIKE '$i' AND jobstatus IN ('T','R') AND starttime > NOW() - INTERVAL '24 HOURS' ORDER BY jobid DESC LIMIT 1; EOD1) retVal=$? # 逻辑判断:执行成功且有返回数据则写入completed,否则写入notcompleted if [[ $retVal -eq 0 && -n "$jobs_notcompleted" ]]; then echo "$jobs_notcompleted" >> jobscompleted.txt else # 可自定义无匹配时的提示文本,或直接写入空内容 echo "作业[$i]过去24小时内无成功/运行记录" >> jobsnotcompleted.txt # 若需保留原查询输出(空内容),替换为:echo "$jobs_notcompleted" >> jobsnotcompleted.txt fi done
关键说明
- PostgreSQL设计上不会因
SELECT无匹配行返回非0退出码,因此必须通过检查输出内容是否为空来判断是否有结果 -n "$jobs_notcompleted"用于判断变量是否非空,即是否有查询结果返回
内容的提问来源于stack exchange,提问作者veeranjaneya reddy
相关产品推荐
相关产品推荐

