[英]Redirect stdout and stderr to different program without changing exit code
[英]Replace exit code based on stdout?
我有一个命令,我想编写一些脚本,但它为我不关心的场景返回一个非零退出代码。 基于标准输出响应可以检测到这种情况,因此我想“更正”状态代码,以便我可以围绕它编写一些脚本。
例如
$ hg evolve
nothing to evolve on current working copy parent
(6 other orphan in the repository, do you want --any or --rev)
$ echo $?
2
是否有一些方便的方法可以用纯 bash 包装它,以便我可以更改状态代码 IFF stdout 匹配某些正则表达式?
例如
fixstatus '^nothing to evolve\b' -- hg evolve # would return 0 if stdout from hg evolve matches that regex, otherwise returns whatever it would have normally returned
类似的东西。 我不认为我可以用管道解决它,因为那样退出代码将匹配最终命令。
您可以执行以下操作:
output=$( hg evolve )
status=$?
if echo "$output" | grep -q '^nothing to evolve\b'; then
status=0
fi
sh -c "exit $status" # Set $?
所以,在一个函数中,它可能看起来像:
fixstatus() {
local output status regex
regex="$1"
shift
output=$( "$@" )
status=$?
if echo "$output" | grep -q -- "$regex"; then
status=0
fi
printf "%s\n" "$output"
return $status
}
并称之为: fixstatus '^nothing to evolve\\b' hg evolve
由于您使用的是 bash,您还可以使用[[ ... =~ ... ]]
而不是grep
。
尽可能在解释器本身中:
output="$( hg evolve )"
status=$?
case "$output" in
"nothing to evolve"*) status=0;;
esac
exit $status
从技术上讲,这与您使用的正则表达式并不完全匹配,因此这里有一个替代方案:
output="$( hg evolve )"
status=$?
pat='^nothing to evolve\b'
if [[ "$output" =~ $pat ]] # $pat not quoted
then status=0
fi
exit $status
原来hg
正在写入标准错误。 稍微调整了威廉的答案,现在它似乎适用于我的用例:
#!/bin/bash
regex="$1"
shift
{ output=$("$@" 2>&1 >&3 3>&-); } 3>&1
status=$?
if \grep -q --perl-regexp -- "$regex" <<<"$output"; then
exit 0
fi
exit $status
我把它放在~/bin/errstatus0
以便其他脚本可以运行它(别名不起作用),并在~/.hgrc
创建了一个别名:
_evolve = !errstatus0 '^nothing to evolve\b' hg evolve --all --no-update
现在hg _evolve
返回我想要的状态,我可以用&&
链接它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.