文章出处:
The set
lines
- 这些行故意导致您的脚本失败。等等,什么?相信我,这是一件好事。
- 使用这些设置,某些常见错误将导致脚本立即失败。 否则,您可能会忽略那些隐藏的错误,这些错误只有在生产中才被发现。
-
set -euxo pipefail
是下面4个命令的简称:
set -e
set -u
set -o pipefail
set -x
set -e
如果任何命令具有非零的退出状态,该选项指示 bash 立即退出。在所有广泛使用的通用编程语言中,未处理的运行时错误(无论是 Java 中抛出的异常、C 中的分段错误,还是 Python 中的语法错误)都会立即停止程序的执行;不执行后续行。
- 默认情况下,bash 不这样做。如果您在命令行上使用 bash,则此默认行为正是您想要的
- 如果脚本中的一行失败,但最后一行成功,则整个脚本都有一个成功的退出代码。这很容易忽略错误。
set -x
启用 shell 模式,将所有执行的命令都打印到终端。
这是 set -x 的典型用例:在执行每个命令时打印它可以帮助您可视化脚本的控制流。
set -u
影响变量。
除了 $*
和 $@
,对您之前未定义的任何变量的引用都是一个错误,并导致程序立即退出。
出于各种充分的理由,Python、C、Java 等语言的行为方式都相同。一个是错别字不会在您没有意识到的情况下创建新变量。
#!/bin/bash
firstName="Aaron"
fullName="$firstname Maxwell"
echo "$fullName"
- 第三行的右边是“firstname”,全小写,而不是驼峰式的“firstName”。如果没有 -u 选项,这将是一个静默错误。但是使用 -u 选项,脚本在该行以退出代码 1 退出,将消息“firstname: unbound variable”打印到 stderr。
- 这就是您想要的:让它立即显式失败,而不是创建可能为时已晚发现的细微错误。
set -o pipefail
此设置可防止管道中的错误被屏蔽。
如果管道中的任何命令失败,则该返回码将用作整个管道的返回码。默认情况下,即使成功,管道的返回码也是最后一条命令的返回码。
$ grep some-string /non/existent/file | sort
grep: /non/existent/file: No such file or directory
% echo $?
0
- 在这里,grep 的退出代码为 2,向 stderr 写入错误消息,向 stdout 写入空字符串。
- 然后这个空字符串通过 sort,空字符串作为有效输入,并返回状态码 0。
- 这对命令行很好,但对 shell 脚本不利:您肯定希望脚本立即退出,并使用非零退出代码......像这样:
$ set -o pipefail
$ grep some-string /non/existent/file | sort
grep: /non/existent/file: No such file or directory
$ echo $?
2
Setting IFS
IFS 变量,代表内部字段分隔符
#!/bin/bash
IFS=$' '
items="a b c"
for x in $items; do
echo "$x"
done
IFS=$'\n'
for y in $items; do
echo "$y"
done
... will print out this:
a
b
c
a b c
- 对于第一个循环,IFS 是一个空格,这意味着单词由空格字符分隔。
- 对于第二个循环,“单词”由换行符分隔,这意味着 bash 将“项目”的整个值视为一个单词。如果 IFS 有多个字符,则将对这些字符中的任何一个进行拆分。
- 为什么我们要将 IFS 设置为由制表符和换行符组成的字符串?因为它在迭代循环时为我们提供了更好的行为。不太可能导致令人惊讶和令人困惑的错误。
这在使用 bash 数组时很明显:
#!/bin/bash
names=(
"Aaron Maxwell"
"Wayne Gretzky"
"David Beckham"
)
echo "With default IFS value..."
for name in ${names[@]}; do
echo "$name"
done
echo ""
echo "With strict-mode IFS value..."
IFS=$'\n\t'
for name in ${names[@]}; do
echo "$name"
done
## 输出结果
With default IFS value...
Aaron
Maxwell
Wayne
Gretzky
David
Beckham
With strict-mode IFS value...
Aaron Maxwell
Wayne Gretzky
David Beckham
网友评论