如何修改Linux Shell脚本,将错误信息纳入格式化输出?
Bash脚本错误捕获与格式化输出优化
问题描述
需要对脚本的输出(包括意外错误信息)进行JSON格式封装,尝试用trap拦截ERR信号实现,但错误场景下无法将错误信息填入JSON的result字段。
原脚本:
#!/bin/bash set -o errtrace status=false trap "print " ERR print() { echo "{\"status\":$status,\"result\":\"$1\"}" exit 0 } main(){ arg=$1 if [ \"$arg\" == \"0\" ];then status=true print "successfully finish" else cat /a/b/c/d >>/dev/null echo "abnormal termination" fi } main \"$@\"
现有输出
- 成功场景(符合预期):
# bash format-print.sh 0 {"status":true,"result":"successfully finish"}
- 错误场景(不符合需求):
# bash format-print.sh 1 cat: /a/b/c/d: No such file or directory {"status":false,"result":""}
期望输出
# bash format-print.sh 1 cat: /a/b/c/d: No such file or directory {"status":false,"result":"cat: /a/b/c/d: No such file or directory"}
修复方案
核心修改说明
- 修正
trap触发逻辑:原trap未传递错误信息,调整为触发时捕获出错命令的stderr输出。 - 添加JSON转义处理:避免错误信息中的特殊字符破坏JSON结构。
- 清理多余转义符:移除原脚本中不必要的
\"转义,符合Bash脚本语法规范。
修改后的完整脚本
#!/bin/bash set -o errtrace status=false # 转义JSON特殊字符,防止格式错误 escape_json() { printf '%s' "$1" | sed -e 's/"/\\"/g' -e 's/\//\\\//g' -e 's/\n/\\n/g' } print() { local escaped_content=$(escape_json "$1") echo "{\"status\":$status,\"result\":\"$escaped_content\"}" exit 0 } # 捕获ERR信号,收集错误信息并传递给print函数 trap ' # 捕获出错命令的stderr输出 local error_msg=$("$BASH_COMMAND" 2>&1 >/dev/null) print "$error_msg" ' ERR main(){ arg=$1 if [ "$arg" == "0" ];then status=true print "successfully finish" else cat /a/b/c/d >>/dev/null fi } main "$@"
测试验证
- 成功场景输出不变:
# bash format-print.sh 0 {"status":true,"result":"successfully finish"}
- 错误场景符合预期:
# bash format-print.sh 1 cat: /a/b/c/d: No such file or directory {"status":false,"result":"cat: /a/b/c/d: No such file or directory"}
额外说明
- 若不需要在控制台输出原始错误信息,可将
trap中的命令改为local error_msg=$(eval "$BASH_COMMAND" 2>&1 >/dev/null),仅输出格式化后的JSON。 set -o errtrace的设置是必要的,确保子函数main中的错误能被全局trap捕获。
内容的提问来源于stack exchange,提问作者moluzhui
相关产品推荐
相关产品推荐

