linux - 一个是什么意思!在shell中的命令之前?

标签 linux bash shell unix sh

以感叹号开头的 shell 命令(shell 脚本的一部分)的用途是什么?

具体例子:

在 foo.sh 中:

#!/usr/bin/env bash
set -e
! docker stop foo
! docker rm -f foo
# ... other stuff

我知道没有空格感叹号用于历史替换和! <expression>根据man page可用于评估“True if expr is false”。但是在示例上下文中对我来说没有意义。

最佳答案

TL;DR:这只是在您使用它的特定行中绕过 set -e 标志。


添加添加到 hek2mgl's correct and useful answer .

你有:

set -e
! command

Bash Reference Manual → Pipelines描述:

Each command in a pipeline is executed in its own subshell. The exit status of a pipeline is the exit status of the last command in the pipeline (...). If the reserved word ‘!’ precedes the pipeline, the exit status is the logical negation of the exit status as described above. The shell waits for all commands in the pipeline to terminate before returning a value.

这意味着命令前面的 ! 否定它的退出状态:

$ echo 23
23
$ echo $?
0
                # But
$ ! echo 23
23
$ echo $?
1

或者:

$ echo 23 && echo "true" || echo "fail"
23
true
$ ! echo 23 && echo "true" || echo "fail"
23
fail

退出状态在很多方面都很有用。在您的脚本中,与 set -e 一起使用会使脚本在命令返回非零状态时退出。

因此,当你有:

set -e
command1
command2

如果 command1 返回非零状态,脚本将完成并且不会继续执行 command2

不过,还有一个有趣的地方要提,在 4.3.1 The Set Builtin 中有描述。 :

-e

Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists), or a compound command (see Compound Commands) returns a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.


考虑到所有这些,当你有:

set -e
! command1
command2

您所做的是绕过 command1 中的 set -e 标志。为什么?

  • 如果command1 运行正常,它将返回零状态。 ! 将否定它,但 set -e 不会触发退出,因为它来自与 ! 反转的返回状态,如上所述。
  • 如果 command1 失败,它将返回非零状态。 ! 将否定它,因此该行最终将返回零状态,脚本将正常继续。

关于linux - 一个是什么意思!在shell中的命令之前?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47261313/

相关文章:

java - tr Locale、Windows 7 和 Linux 中的日期格式给出 2 个结果

arrays - Bash 数组 : Unexpected Syntax error

linux - sed -i 不适用于 MacO(sed : 1) and work on linux

bash - 如何优雅地停止 bash 脚本中的无限循环?

shell - 在 awk 中按特定顺序打印文件

php - 共享 Apache 2.0 模块与静态 Apache 模块

java - 从 java 访问一个字符设备文件

java - Play 不断写入光盘?在 Amazon ec2 上导致更高的账单

bash - 用于多文件夹文件重命名的更惯用的 BASH 脚本

bash 在一行中打印多行单词