如果命令失败,如何让管道*完全*停止?

问题描述 投票:0回答:2

我正在使用此代码来使用 jq 就地格式化 json 文件

jq . foo.json | sponge foo.json

它工作得很好,但有一个致命的缺陷 - 如果

jq . foo.json
失败(例如,由于解析错误),管道只会继续滴答作响,不会向
foo.json
写入任何内容,从而擦除文件。

我想要的行为与

foo | bar
相同,但是如果
foo
失败,
bar
将不会被执行。
set -o pipefail
看起来很有希望,但事实证明事实并非如此。这感觉像是一个足够常见的用例,会有一些巧妙的简写,但我无法弄清楚。

bash pipe
2个回答
1
投票

可以分享一下json文件吗?

你可以试试这个。

jq . foo.json > temp.json && mv temp.json foo.json

这将首先运行 jq 。 foo.json > temp.json。

如果 jq 成功,它将把 temp.json 移动到 foo.json,并用格式化的 JSON 覆盖它。

如果jq失败,temp.json不会更新,foo.json将保持不变。

更新:

if jq . foo.json > foo.json.tmp && mv foo.json.tmp foo.json; then
    echo "JSON formatted successfully"
else
    echo "Failed to format JSON"
    rm -f foo.json.tmp
fi

或者你可以尝试这个,它会将输出写入 dev/null 而不是创建文件。

jq . foo.json > foo.json.tmp 2>/dev/null && mv foo.json.tmp foo.json

如果你想尝试 jq 的 try/catch 函数,我想它会是这样的。

jq 'try . catch empty' foo.json > foo.json.tmp && mv foo.json.tmp foo.json

0
投票

jq 通过 try/catch 功能完美地处理了这个问题:
请参阅此处文档

© www.soinside.com 2019 - 2024. All rights reserved.