如何让脚本等待curl命令完成下载并在失败时触发错误?
解决curl等待下载完成及失败触发错误的方法
核心问题分析
当前命令curl "http://mydomain/api/v1/subscribers" -u 'user:pass' | json_pp >> new.json存在两个关键问题:
- 管道机制会让
json_pp在curl未完全输出内容时就开始处理,且无法直接感知curl的执行状态 - 即使
curl请求失败,>>仍会向目标文件追加无效内容(错误信息或空内容),且脚本会继续执行后续逻辑
具体解决步骤
1. 确保脚本等待curl完成并捕获执行状态
curl本身会阻塞至请求完成,核心是要捕获它的退出码(0表示成功,非0表示失败),以下两种方案可按需选择:
方案一:用临时文件中转,避免管道状态丢失
# 先将curl结果写入临时文件,同时捕获退出码 curl -o temp_subs.json "http://mydomain/api/v1/subscribers" -u 'user:pass' curl_exit=$? # 检查curl是否执行成功 if [ $curl_exit -ne 0 ]; then echo "curl请求失败,退出码:$curl_exit" rm -f temp_subs.json # 清理无效临时文件 exit 1 # 触发错误,终止脚本后续流程 fi # 处理JSON并追加到目标文件 json_pp < temp_subs.json >> new.json rm -f temp_subs.json # 清理临时文件
方案二:开启pipefail传递管道错误状态
如果坚持使用管道,可先开启pipefail选项,让管道的整体退出码等于第一个失败命令的退出码:
# 开启pipefail,确保管道中任意命令失败都会返回错误码 set -o pipefail # 执行请求并处理JSON,捕获整体退出码 curl "http://mydomain/api/v1/subscribers" -u 'user:pass' | json_pp >> new.json pipe_exit=$? # 检查管道执行是否成功 if [ $pipe_exit -ne 0 ]; then echo "请求或JSON处理失败,退出码:$pipe_exit" exit 1 # 触发错误,终止脚本后续流程 fi
2. 额外优化建议
- 避免直接追加:若
curl失败,直接追加会污染目标文件,建议先写入临时文件,确认成功后再合并到目标文件 - 增强错误排查:给
curl加上-sS参数(静默模式但显示错误),或-v参数(输出详细请求日志),方便定位失败原因 - 防止文件冲突:若脚本可能被多进程执行,可使用
flock命令锁定目标文件,避免写入冲突
内容的提问来源于stack exchange,提问作者gareth0402
相关产品推荐
相关产品推荐

