Shell 中set -e set -x set +e 的区别

Linux 中set -e/set -x/set +e 的区别

#!/bin/bash

set -e
# 在shell脚本开头加上set -e,这句话告诉bash 如果任何语句的执行结果不是true,
# 就直接退出shell脚本

shell 代码执行的返回值

  • 取的上条命令的返回值
    • echo $?
    • $? 变量是上条命令执行的结果,通常为0,或者1,
      • 正常执行/成功执行,返回0
      • 错误执行/执行失败,返回1
    • 例子:
      • grep 命令,如果有匹配的字符串,返回值会是0,且会打印出匹配字符串的行
      • 如果没有匹配,会返回 1

set -u

  • 实例
#!/usr/bin/env bash 
echo $a
echo "hello shell "
  • 上面代码中 $a是一个不存在的变量,一般来说,执行到 2行的时候会因为不存在该变量而直接报错,然鹅 bash 会忽略掉这个不存在的变量继续向下执行,
  • set -u 是用来改变这种行为,脚本在头部加上他,遇到不存在的变量就会报错,终止脚本执行。
  • 等价写法
    • set -o nounset

set -x

  • 默认脚本执行情况下,屏幕只显示运行结果,没有其他内容,如果多个命令连续执行,运行结果就会连续输出,分不清楚哪行命令的执行,与结果
  • set -x 用来在显示运行结果之前,先输出执行的那条命令

#!/usr/bin/env bash
set -x

echo addicated

output
$ bash script.sh
+ echo bar
bar
  • 可以看到,执行之前的shell 内部脚本是 +待执行代码的形式输出,方便进行调试

set -e

  • 根据返回值判断,命令是否运行失败。但是,某些命令的非0返回可能不表示失败,
  • 亦或者,开发者在希望命令失败的情况下,让脚本继续执行下去,这时可以先关闭 set -e,该命令执行结束之后,再重新打开 set -e
set +e
command1
command2
set -e
  • 上例中,set +e 表示关闭 -e选项,即使出错也依然向下执行脚本
  • set -e 为打开 -e选项,脚本失败,即刻退出执行
  • 等价写法
    • set -o errexit

set -e 的例外

  • set -e 有一个例外情况,不适用于管道命令

所谓管道命令,就是多个子命令通过管道运算符(|)组合成为一个大的命令。Bash 会把最后一个子命令的返回值,作为整个命令的返回值。也就是说,只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e就失效了。

#!/usr/bin/env bash
set -e
foo | echo addicated

echo end


$ bash script.sh
a
script.sh:行4: foo: 未找到命令
end

  • 上面代码中,foo是一个不存在的命令,但是foo | echo addicated 这个管道命令会执行成功,导致后面的echo end 会继续执行。
  • set -o pipefail用来解决这种情况,只要一个子命令失败,整个管道命令就失败,脚本就会终止执行。

#!/usr/bin/env bash
set -eo pipefail

foo | echo a
echo end

$ bash script.sh
a
script.sh:行4: foo: 未找到命令

可以发现 echo end 就没有被执行,成功被阻断了

综合运用

  • set 命令的上面这4个参数,一般可以放在一起使用,根据需求调配
set -euxo pipefail

# 含义
# -u 存在未定义的变量就报错
# -x 执行每条命令之前先输出该命令
# -o pipefail 对管道命令中的每条命令都进行错误控制,出错即跳出
# -e 出现返回值非零即退出脚本执行

你可能感兴趣的:(学习记录,shell)