簡體   English   中英

如何檢查是否$? 在 unix shell 腳本中不等於零?

[英]How to check if $? is not equal to zero in unix shell scripting?

我有一個腳本,它使用 test 命令來檢查$? (上次執行命令的返回碼)不為零。 代碼如下:-

$? 是最后執行的命令的退出狀態。

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

然而,這種驗證方式不適用於字符串,因為 get syntax error 。 請提出一個合適的替代方案。

先把它放在一個變量中,然后嘗試測試一下,如下圖

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

這應該有幫助。


編輯:如果上述內容沒有按預期工作,那么您可能沒有使用$? 在正確的地方。 它必須是您需要捕獲返回狀態的命令之后的下一行 即使目標之間有任何其他單個命令並且您捕獲它的返回狀態,您也將檢索此中間命令的returns_status,而不是您期望的那個。

你不需要測試是否$? 不是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

執行腳本后試試這個:

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

我不知道你是如何得到$?的字符串的$? 但你可以這樣做:

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

這是針對類似問題提出的解決方案

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

用法:

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

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

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

我整理了一些可能有助於了解返回值與返回字符串如何工作的代碼。 可能有更好的方法,但這是我通過測試發現的。

#!/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"
function assert_exit_code {
    rc=$?; if [[ $rc != 0 ]]; then echo "$1" 1>&2; fi
}

...

execute.sh

assert_exit_code "execute.sh has failed"

將 set -o pipefail 放在任何腳本的開頭,以返回任何失敗

如果你這樣做了,並且測試失敗了,但 T 恤沒有。 默認情況下 $? 只需要最后一個命令成功,在這種情況下是“tee”命令

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM