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

如何让管道在前置命令失败时彻底终止?防止JSON文件被误清空

原地格式化JSON文件时避免因解析错误清空文件

我之前用这条命令原地格式化JSON文件:

jq . foo.json | sponge foo.json

它能正常完成格式化,但有个致命问题:如果jq . foo.json执行失败(比如JSON解析错误),管道还是会继续执行,导致foo.json被写入空内容直接清空。

我需要的是:只有当jq执行成功时,才让后续命令处理并覆盖原文件;如果jq失败,原文件保持原样。比如:

  • 对于格式合法的输入:
    "foo"
    
    希望格式化后变成:
    "foo"
    
  • 对于格式错误的输入(比如未闭合的字符串):
    "foo
    
    希望原文件保持不变,而不是被清空。

简便解决方案

方法1:临时文件中转(最稳妥直观)

用临时文件先保存jq的处理结果,只有jq执行成功时,再用临时文件替换原文件:

jq . foo.json > foo.tmp && mv foo.tmp foo.json

逻辑很简单:&&是短路运算符,只有前面的jq命令返回成功状态码(0)时,才会执行后面的mv命令。如果jq解析失败,临时文件会保留错误输出(或空内容),但原文件不会被修改。

如果担心临时文件残留,可以加上自动清理逻辑:

trap 'rm -f foo.tmp' EXIT
jq . foo.json > foo.tmp && mv foo.tmp foo.json

trap会在脚本退出时自动删除临时文件。

方法2:利用PIPESTATUS判断管道前序命令状态

在bash中,可以通过PIPESTATUS数组获取管道中每个命令的退出状态,只在jq成功时执行sponge:

jq . foo.json | { [[ ${PIPESTATUS[0]} -eq 0 ]] && sponge foo.json; }

${PIPESTATUS[0]}对应管道中第一个命令(也就是jq)的退出码,等于0说明执行成功,此时才会调用sponge写入原文件。

效果验证

  • 处理合法JSON时,两种方法都能正常格式化并覆盖原文件;
  • 处理非法JSON时,jq会输出解析错误,后续的mv或sponge都不会执行,原文件内容保持不变。

内容的提问来源于stack exchange,提问作者Mason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:17:45