You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取PostgreSQL无匹配行的退出码及Bacula脚本调整求助

解决Bacula作业筛选脚本的无匹配行判断问题

问题核心

你的脚本当前存在两个关键问题:

  1. PostgreSQL的psql客户端执行SELECT语句时,即使无匹配行也会返回退出码0(仅SQL语法错误、连接失败等场景才会返回非0),导致无匹配行的结果错误写入jobscompleted.txt
  2. 无匹配行时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:05:22