Bash总是返回错误代码等于0

3

我正在尝试检查一个文件夹是否是git或svn仓库的一部分。 我使用以下命令来获取并将错误代码存储在变量中。

RSVN=`svn status &> /dev/null; echo $?`
RGIT=`git status &> /dev/null; echo $?`

事情是我总是得到0作为错误代码。
我在命令行中尝试,得到了预期的结果。
user@host trunk$ svn status &> /dev/null;
user@host  trunk$ echo $?
0
user@host  trunk$ git status &> /dev/null;
user@host  trunk$ echo $?
128

但是当我运行脚本时,会出现以下错误:
+ + svn status

+ echo 0
+ RSVN=0
M       buildpackage
+ git status
+
+ echo 0
fatal: Not a git repository (or any parent up to mount point /build)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
+ RGIT=0

这个被称为下标的方法是由其他脚本调用的。 第一个脚本。
#!/bin/sh -x
#set -e

#do stuf 

. ../../../tools/second_script.sh

第二个脚本

#!/bin/sh -x
set -e

#do stuf 

RSVN=`svn status &> /dev/null; echo $?`
RGIT=`git status &> /dev/null; echo $?`

你知道这是为什么吗?这是发生了什么问题?

你尝试过不带 &,看它是否按预期工作了吗? - Fazlin
1
可以运行。恐怕我们需要看一下你的脚本。 - kirelagin
我之前没试过,但是后来尝试了一下,结果还是一样的。 - fcptin
你能更精确地说明你在哪里得到了零状态吗?使用 set -e 命令,你的脚本将在第一个非零退出状态时停止。 - simno
@simno 有一个跟踪输出。 - kirelagin
2个回答

3
变量在命令执行之前被 shell 替换了。请使用以下方法:
svn status &> /dev/null; RSVN=$?
git status &> /dev/null; RGIT=$?

实际上,不要再使用全大写的变量名:有一天你会写 PATH=$(something) ,然后不知道为什么你的脚本就坏了。

这是有道理的,但我仍然在两个命令上得到了0,并且使用set -e如果一个命令失败,它将退出我的脚本。我可能做错了什么。 $? 在脚本中似乎不起作用。 目前我做了一个小的解决方法。 - fcptin
你的答案是正确的,我尝试了一下没有 set -e 标志,它可以正常工作。 我所做的是在之前加上 set +e,然后再加上 set -e,这样就可以正常工作了。 谢谢,我会将其标记为正确答案。 - fcptin
是的,这就是 set -e 应该做的。 - glenn jackman

0

目前我采用另一种方法,它可以满足我的需求,但与使用退出代码相比,它是一个更糟糕的解决方案。

改为:

RSVN=`svn status &> /dev/null; echo $?`
RGIT=`git status &> /dev/null; echo $?`

使用:
RSVN=`svn status 2>&1 | grep "is not a working copy" | wc -l`
RGIT=`git status 2>&1 | grep "Not a git repository"  | wc -l`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接