如何检查命令是否成功?


234

有什么方法可以检查执行命令是否出错?

范例:

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

我已经尝试过这样做,但是似乎没有用。我不怎么做


9
最好将$(foo)放在反引号`foo`上,因为您可以嵌套它,并且更容易与撇号区分开。
用户未知

1
顺便说一句,valid在调用它之前,您需要定义一个函数()。
wjandrea

Answers:


344

返回值存储在中$?。0表示成功,其他表示错误。

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

像任何其他文本值一样,您可以将其存储在变量中以备将来比较:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

有关可能的比较运算符,请参见man test


很好...我可以保留输出错误吗?? !! ,因为在这种情况下我有2个错误:命令错误“文本” ex,找不到文件,而我的错误“文本”例如在这种情况下失败
moata_u 2011年

@moata_u:您可以将值存储在变量中,如我的答案所示。
Lekensteyn 2011年

@moata_u:您需要;elseand 之前加上一个fi:`if ...; 然后 ...; 否则...; fi
Lekensteyn 2011年


1
@Blauhirn [ $? ](或等效地,test $?)不起作用,因为$?计算得出的数字(0、1等)不为空。请参阅文档test:“如果省略EXPRESSION,则'test'返回false。如果EXPRESSION是单个参数,则如果参数为null,则'test'返回false,否则返回true。”
Lekensteyn

87

如果您只需要知道命令是成功还是失败,就不必进行测试$?,只需直接测试命令即可。例如:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

并且将输出分配给变量不会改变返回值(当然,除非当stdout当然不是终端时它的行为有所不同)。

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals进行if更详细的说明。


如果您想执行分支以外的其他操作,例如将是否失败的布尔值存储到.ini中,该怎么办?然后,您的输出变量不会执行此操作,但是$?会执行此操作,因此您在说直接测试命令绝对更好方面是不正确的。
蒂莫西·斯旺

当使用local命令(即在输出上local foo=$(false); echo $?;产生)时0,将输出分配给变量可能会更改返回值。但是local仅在bash函数内部相关。
Cromax

26
command && echo OK || echo Failed

如果command在屏幕上返回错误,该如何隐藏?
Sigur

如果command将错误写到stderr,则可以使用形式command 2> /dev/null && echo OK || echo Failed。该2> /dev/null重定向标准错误输出/dev/null。但是,某些实用程序会将错误写入stdout(即使这是错误的做法)。在这种情况下,您可以从重定向中省略2,但是您将丢失该命令的任何输出。这种检查成功的方法适用于简单的三元逻辑,但是对于更复杂的行为,最好检查$?命令是否成功,或者使用if@geirha的答案中概述的block方法。
本德尔(Bender)最伟大的作品

17

$?应包含前一个命令的退出状态,应为零(无错误)。

因此,类似

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

在大多数情况下,使用&&构造来链接需要相互依赖的命令会更容易。因此,cd /nonexistant && echo success!不会 &&之前呼应的成功,因为该命令中断。这样做的必然结果是||,其中cd /nonexistant || echo fail 回声失败,因为CD失败。(如果使用|| exit之类的东西,它将很有用,如果前一个命令失败,它将结束脚本。)


很好...我可以保留输出错误吗?? !! ,因为在这种情况下我有2个错误:命令错误“文本” ex,找不到文件,而我的错误“文本”例如在这种情况下失败
moata_u 2011年


5
command && echo $? || echo $?

你的意思是command; echo $?
哈维尔·巴齐

不,我的行是正确的,无论成功或失败,它都会以数字形式给出实际结果代码。
modrobert

1
好吧,请向我解释这些区别:true && echo $? || echo $?/ true; echo $?false && echo $? || echo $?/ false; echo $?-您会发现,它们的作用完全相同:D
Javier Buzzi,

是的,结果相同,但没有条件。最初询问的问题是“如何检查命令是否成功?”,这是基于先前的答案。我想一个更好的例子是:command && echo "success: $?" || echo "fail: $?"
modrobert

5

应该注意的是,if...then...fi&&/ ||方法的类型涉及我们要测试的命令返回的退出状态(成功时为0);但是,如果命令失败或无法处理输入,则某些命令不会返回非零退出状态。这意味着通常的if&&/ ||方法对那些特定命令不起作用。

例如,在Linux上file,如果GNU 接收到不存在的文件作为参数并且find无法找到指定的文件用户,则GNU 仍将以0退出。

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

在这种情况下,我们可能会处理这种情况的一种可能方式是读取stderr/ stdin消息,例如,由file命令返回的消息,或解析命令的输出,例如in find。为此,case可以使用语句。

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(这是我对unix.stackexchange.com有关问题的回答的转贴


1

正如许多其他答案中所述,$?将对will做一个简单的测试,就像这样

if [ $? -eq 0 ]; then something; fi

如果要测试命令是否失败,则可以在bash(但过大)的情况下使用较短的版本,如下所示:

if (($?)); then something; fi

这通过使用(( ))算术模式起作用,因此,如果返回命令success,即$? = 0测试将评估为((0))哪个测试false,否则它将返回true

要测试成功,您可以使用:

if ! (($?)); then something; fi

但是它已经比第一个示例短很多了。


1
建设性的批评?


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.