在一个nodejs项目中,我有一个快捷方式yarn lint
,该快捷方式以这种方式运行了两个linter:
lint_1 && lint_2 && lint_3
如果其中任何一个发现错误,它将返回错误代码,结果yarn lint
本身将返回错误代码,结果是-构建失败。
它工作得很好,尽管有一个小问题,但可以捕获所有错误:如果短绒棉失败并显示错误代码-其余的短绒棉将不会执行。
我想要的-执行所有命令(这样它们都将打印所有错误),然后失败。
我知道我可以创建一个bash脚本(将在yarn lint
中运行),逐一收集返回代码,然后运行每个linter,然后检查代码是否为非零-{{ 1}},它将失败exit 1
。但是我想知道是否还有更优雅的方法?
答案 0 :(得分:5)
您可以捕获ERR并设置一个标志。这将运行每个linter,如果其中任何一个失败,则失败退出:
#!/bin/bash
result=0
trap 'result=1' ERR
lint_1
lint_2
lint_3
exit "$result"
答案 1 :(得分:2)
我想要的-执行所有命令(这样它们都会打印所有错误),然后失败
基本上,我们有一个要捕获的退出代码列表。如果其中任何一个非零,我们需要将一个变量设置为具有非零值。将其扩展为列表,如下所示:
result=0
if ! lint_1; then result=1; fi
if ! lint_2; then result=1; fi
if ! lint_3; then result=1; fi
exit "$result"
作为一名程序员,我看到这里有一个模式。因此我们可以使用数组,但是bash没有2d数组。使用eval
可以解决引用的参数。这是可行的。您必须使用eval
来双重清空数组“指针” /名称,但是可以。请注意,eval
是evil
。
cmds_1=(lint_1 "arg with spaces you pass to lint_1")
cmds_2=(lint_2)
cmds_3=(lint_3)
result=0
# compgen results list of variables starting with `cmds_`
# so naming is important
for i in $(compgen -v cmds_); do
# at first, `$i` is only expanded
# then the array is expanded `"${cmds_?[@]}"`
if ! eval "\"\${$i[@]}\""; then
result=1
fi
done
exit "$result"
我们也可以选择xargs。手册中的EXIT STATUS
是123 if __any__ invocation of the command exited with status 1-125
。如果您知道程序将在1-125退出状态之间退出,则可以(通常xargs无论如何都正确处理了不同的退出状态(返回123),但请保持一致):
xargs -l1 -- bash -c '"$@"' -- <<EOF
lint_1 "arg with spaces you pass to lint_1"
lint_2
lint_3
EOF
result=$? # or just exit "$?"
exit "$result"
看起来很干净。附带说明一下,只需将-P <number of jobs>
传递给xargs
,就可以并行执行所有命令。您可以通过处理bash脚本中的错误来适应1-125错误范围。
xargs -l1 -- bash -c '"$@" || exit 1' -- <<EOF
lint_1 "arg with spaces you pass to lint_1"
lint_2
lint_3
EOF
result=$?
exit "$result"
还有另一个想法。在每个命令之后,我们可以在专用文件描述符上输出返回状态。然后从所有返回状态中过滤零,并检查流中是否还有其他状态。如果它们是,我们应该以非零状态退出。这感觉像是一种解决方法,基本上与第一个代码片段相同,但是if ! ....; then result=1; fi
简化为; echo $? >&10
。
tmp=$(mktemp)
(
lint_1 "arg with spaces you pass to lint_1"; echo $? >&10
lint_2; echo $? >&10
lint_3; echo $? >&10
) 10> >(
[ -z "$(grep -v 0)" ]
echo $? > "$tmp"
)
result="$(cat "$tmp"; rm "$tmp")"
exit "$result"
从给出的选项中,我可以选择另一个答案;)或第二个xargs。