86

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

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

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

但是,这种验证方式不适用于字符串,因为 get syntax error 。请提出一个合适的替代方案。

4

10 回答 10

92

Put it in a variable first and then try to test it, as shown below

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

This should help.


Edit: If the above is not working as expected then, there is a possibility that you are not using $? at right place. It must be the very next line after the command of which you need to catch the return status. Even if there is any other single command in between the target and you catching it's return status, you'll be retrieving the returns_status of this intermediate command and not the one you are expecting.

于 2013-03-18T07:02:27.283 回答
52

你不需要测试 if $?is not 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
于 2016-12-23T22:47:59.597 回答
19

执行脚本后试试这个:

if [ $? -ne 0 ];
then
//statements//
fi
于 2016-10-25T12:31:31.263 回答
3

I don't know how you got a string in $? but you can do:

if [[ "x$?" == "x0" ]]; then
   echo good
fi
于 2013-03-18T07:03:33.650 回答
3

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

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

用法:

do-command exit_status && echo "worked" || echo "didnt work"
于 2014-05-08T10:13:46.237 回答
1
<run your last command on this line>
a=${?}
if [ ${a} -ne 0 ]; then echo "do something"; fi

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

于 2013-03-18T10:29:07.170 回答
1
if [ $var1 != $var2 ] 
then 
echo "$var1"
else 
echo "$var2"
fi
于 2015-07-22T07:37:07.300 回答
0

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

#!/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"
于 2020-07-22T20:33:17.090 回答
0

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

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

test | tee /tmp/dump
[ $? -ne 0 ] && echo "failed"
于 2016-12-24T12:41:09.147 回答
0
function assert_exit_code {
    rc=$?; if [[ $rc != 0 ]]; then echo "$1" 1>&2; fi
}

...

execute.sh

assert_exit_code "execute.sh has failed"
于 2015-10-15T20:10:19.083 回答