如何检查$?在unix shell脚本中不等于零?

时间:2013-03-18 06:58:50

标签: shell unix

我有一个脚本,它使用test命令检查$?(最后执行的命令的返回码)是否不等于零。代码如下: -

$?是最后一个执行命令的退出状态。

if (test $? -ne 0)
then
//statements//
fi

然而,这种验证方式对于字符串不起作为get语法错误。请为此建议一个合适的替代方案。

10 个答案:

答案 0 :(得分:45)

首先将其放入变量中,然后尝试对其进行测试,如下所示

ret=$?
if [ $ret -ne 0 ]; then
        echo "In If"
else
        echo "In Else"
fi

这应该有所帮助。


修改:如果上述内容未按预期运行,则您可能无法在正确的位置使用$?它必须是命令之后的下一行,您需要捕获返回状态。即使在目标和捕获它的返回状态之间还有任何其他单个命令,您将检索此中间命令的returns_status而不是您期望的那个。

答案 1 :(得分:19)

我无法相信自从提出这个问题以来,近4年来没有人提到这一点。您真的不需要测试$?是否不是0。 shell提供&&||,因此您可以根据该测试的隐式结果轻松进行分支。

例如:

some_command && {
    # executes this block of code,
    # if some_command would result in:  $? -eq 0
} || {
    # executes this block of code,
    # if some_command would result in:  $? -ne 0
}

您可以删除任一分支,具体取决于您的需要。因此,如果您只想测试失败(即$? -ne 0):

some_command_returning_nonzero || {
    # executes this block of code when:     $? -ne 0
    # and nothing if the command succeeds:  $? -eq 0
}

但是,您在问题中提供的代码是有效的。我很困惑你有语法错误&得出的结论是$?是一个字符串。最有可能导致语法错误的错误代码未提供问题。这一点尤其明显,因为您声称没有其他人的解决方案可以正常工作。发生这种情况时,您必须重新评估您的假设。

注意:如果大括号内的代码返回错误,上面的代码可能会给出令人困惑的结果。在这种情况下,只需使用if命令,如下所示:

if some_command; then
    # executes this block of code,
    # if some_command would result in:  $? -eq 0
else
    # executes this block of code,
    # if some_command would result in:  $? -ne 0
fi

答案 2 :(得分:5)

执行脚本后尝试此操作:

if [ $? -ne 0 ];
then
//statements//
fi

希望它有所帮助......干杯!!!

答案 3 :(得分:2)

我不知道你在$?中是如何得到一个字符串的,但你可以这样做:

if [[ "x$?" == "x0" ]]; then
   echo good
fi

答案 4 :(得分:1)

这是针对类似问题提出的解决方案

exit_status () {
if [ $? = 0 ]
then
    true
else
    false
fi
}

用法:

do-command exit_status && echo "worked" || echo "didnt work"

答案 5 :(得分:1)

我整理了一些代码,可能有助于了解返回值与返回的字符串如何工作。也许有更好的方法,但这是我通过测试发现的。

#!/bin/sh
#
# ro
#

pass(){
  echo passed
  return 0;   # no errors
}
fail(){
  echo failed
  return 1;   # has an error
}
t(){
  echo true, has error
}
f(){
  echo false, no error
}

dv=$(printf "%60s"); dv=${dv// /-}

echo return code good for one use, not available for echo
echo $dv
pass
[ $? -gt 0 ] && t || f
echo "function pass: \$? $?" ' return value is gone'
echo
fail
[ $? -gt 0 ] && t || f
echo "function fail: \$? $?" ' return value is gone'
echo

echo save return code to var k for continued usage
echo $dv
pass
k=$?
[ $k -gt 0 ] && t || f
echo "function pass: \$k $k"
echo
fail
k=$?
[ $k -gt 0 ] && t || f
echo "function fail: \$k $k"
echo

# direct evaluation of the return value
# note that (...) and $(...) executes in a subshell
# with return value to calling shell
# ((...)) is for math/string evaluation

echo direct evaluations of the return value:
echo '  by if (pass) and if (fail)'
echo $dv
if (pass); then
  echo pass has no errors
else
  echo pass has errors
fi
if (fail); then
  echo fail has no errors
else
  echo fail has errors
fi

# this code results in error because of returned string (stdout)
# but comment out the echo statements in pass/fail functions and this code succeeds
echo
echo '  by if $(pass) and if $(fail) ..this succeeds if no echo to stdout from function'
echo $dv
if $(pass); then
  echo pass has no errors
else
  echo pass has errors
fi
if $(fail); then
  echo fail has no errors
else
  echo fail has errors
fi

echo
echo '  by if ((pass)) and if ((fail)) ..this always fails'
echo $dv
if ((pass)); then
  echo pass has no errors
else
  echo pass has errors
fi
if ((fail)); then
  echo fail has no errors
else
  echo fail has errors
fi

echo 
s=$(pass)
r=$?
echo pass, "s: $s  ,  r: $r"
s=$(fail)
r=$?
echo fail, "s: $s  ,  r: $r"

答案 6 :(得分:0)

<run your last command on this line>
a=${?}
if [ ${a} -ne 0 ]; then echo "do something"; fi

使用您要使用的任何命令而不是echo "do something"命令

答案 7 :(得分:0)

if [ $var1 != $var2 ] 
then 
echo "$var1"
else 
echo "$var2"
fi

答案 8 :(得分:0)

function assert_exit_code {
    rc=$?; if [[ $rc != 0 ]]; then echo "$1" 1>&2; fi
}

...

execute.sh

assert_exit_code "execute.sh has failed"

答案 9 :(得分:0)

在任何脚本的开头放置set -o pipefail,以返回任何失败

请你这样做,测试失败,但发球没有。默认为$?只需要最后的命令成功,在这种情况下是“tee”命令

test | tee /tmp/dump
[ $? -ne 0 ] && echo "failed"