Linux 如果命令失败如何退出?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3822621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:39:31  来源:igfitidea点击:

How to exit if a command failed?

linuxbashexitexitstatus

提问by user459246

I am a noob in shell-scripting. I want to print a message and exit my script if a command fails. I've tried:

我是 shell 脚本的菜鸟。如果命令失败,我想打印一条消息并退出我的脚本。我试过了:

my_command && (echo 'my_command failed; exit)

but it does not work. It keeps executing the instructions following this line in the script. I'm using Ubuntu and bash.

但它不起作用。它继续执行脚本中这一行后面的指令。我正在使用 Ubuntu 和 bash。

采纳答案by codaddict

Try:

尝试:

my_command || { echo 'my_command failed' ; exit 1; }

Four changes:

四大变化:

  • Change &&to ||
  • Use { }in place of ( )
  • Introduce ;after exitand
  • spaces after {and before }
  • 更改&&||
  • { }代替使用( )
  • 介绍;之后exit
  • {前后空格}

Since you want to print the message and exit only when the command fails ( exits with non-zero value) you need a ||not an &&.

由于您只想在命令失败时打印消息并退出(以非零值退出),因此您需要一个||不是&&.

cmd1 && cmd2

will run cmd2when cmd1succeeds(exit value 0). Where as

成功cmd2时将运行cmd1(退出值0)。然而

cmd1 || cmd2

will run cmd2when cmd1fails(exit value non-zero).

失败cmd2时将运行cmd1(退出值非零)。

Using ( )makes the command inside them run in a sub-shelland calling a exitfrom there causes you to exit the sub-shell and not your original shell, hence execution continues in your original shell.

Using( )使其中的命令在子 shell 中运行,并exit从那里调用 a会导致您退出子 shell 而不是原始 shell,因此在原始 shell 中继续执行。

To overcome this use { }

为了克服这种使用 { }

The last two changes are required by bash.

bash 需要最后两个更改。

回答by Benoit

Provided my_commandis canonically designed, iereturns 0 when succeeds, then &&is exactly the opposite of what you want. You want ||.

提供的my_command是规范设计的,成功时返回 0,则&&与您想要的完全相反。你要||

Also note that (does not seem right to me in bash, but I cannot try from where I am. Tell me.

另请注意,(这在 bash 中对我来说似乎不正确,但我无法从我所在的位置进行尝试。告诉我。

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}

回答by Alex Howansky

Note also, each command's exit status is stored in the shell variable $?, which you can check immediately after running the command. A non-zero status indicates failure:

另请注意,每个命令的退出状态都存储在 shell 变量 $? 中,您可以在运行命令后立即检查该变量。非零状态表示失败:

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi

回答by Daenyth

The other answers have covered the direct question well, but you may also be interested in using set -e. With that, any command that fails (outside of specific contexts like iftests) will cause the script to abort. For certain scripts, it's very useful.

其他答案已经很好地涵盖了直接问题,但您可能也有兴趣使用set -e. 这样,任何失败的命令(在if测试等特定上下文之外)都将导致脚本中止。对于某些脚本,它非常有用。

回答by Grant Birchmeier

I've hacked up the following idiom:

我修改了以下习语:

echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Done."

Precede each command with an informative echo, and follow each command with that same
if [ $? -ne 0 ];...line. (Of course, you can edit that error message if you want to.)

在每个命令之前使用信息性回显,并在每个命令之后使用同一
if [ $? -ne 0 ];...行。(当然,如果您愿意,您可以编辑该错误消息。)

回答by damienfrancois

If you want that behavior for all commands in your script, just add

如果您希望脚本中的所有命令都具有该行为,只需添加

  set -e 
  set -o pipefail

at the beginning of the script. This pair of options tell the bash interpreter to exit whenever a command returns with a non-zero exit code.

在脚本的开头。这对选项告诉 bash 解释器在命令以非零退出代码返回时退出。

This does not allow you to print an exit message, though.

但是,这不允许您打印退出消息。

回答by alexpirine

You can also use, if you want to preserve exit error status, and have a readable file with one command per line:

如果你想保留退出错误状态,你也可以使用,并有一个每行一个命令的可读文件:

my_command1 || exit $?
my_command2 || exit $?

This, however will not print any additional error message. But in some cases, the error will be printed by the failed command anyway.

但是,这不会打印任何其他错误消息。但在某些情况下,无论如何失败的命令都会打印错误。

回答by kozel

The trapshell builtin allows catching signals, and other useful conditions, including failed command execution (i.e., a non-zero return status). So if you don't want to explicitly test return status of every single command you can say trap "your shell code" ERRand the shell code will be executed any time a command returns a non-zero status. For example:

所述trap外壳内置允许捕获的信号,以及其他有用的条件,包括失败的命令执行(即,非零返回状态)。因此,如果您不想显式测试每个命令的返回状态,您可以说trap "your shell code" ERR,只要命令返回非零状态,就会执行 shell 代码。例如:

trap "echo script failed; exit 1" ERR

trap "echo script failed; exit 1" ERR

Note that as with other cases of catching failed commands, pipelines need special treatment; the above won't catch false | true.

请注意,与捕获失败命令的其他情况一样,管道需要特殊处理;以上不会赶上false | true