From 74efe43f5adda67abc89149c602f07260d0dd114 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 17 Dec 2020 14:51:06 +0800 Subject: [PATCH] docs(set): edit set -E --- chapters.yml | 2 +- docs/debug.md | 2 +- docs/set.md | 59 +++++++++++++++++++++++++++++++++++++++++++++---- docs/startup.md | 2 +- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/chapters.yml b/chapters.yml index 281e3c5..1c7d663 100644 --- a/chapters.yml +++ b/chapters.yml @@ -13,7 +13,7 @@ - loop.md: 循环 - function.md: 函数 - array.md: 数组 -- set.md: set 命令 +- set.md: set 命令,shopt 命令 - debug.md: 脚本除错 - mktemp.md: mktemp 命令,trap 命令 - startup.md: 启动环境 diff --git a/docs/debug.md b/docs/debug.md index 8a5445b..bd7db07 100644 --- a/docs/debug.md +++ b/docs/debug.md @@ -43,7 +43,7 @@ cd $dir_name && rm * ## `bash`的`-x`参数 -`bash`的`-x`参数可以在执行每一行命令之前,打印该命令。这样就不用自己输出执行的命令,一旦出错,比较容易追查。 +`bash`的`-x`参数可以在执行每一行命令之前,打印该命令。一旦出错,这样就比较容易追查。 下面是一个脚本`script.sh`。 diff --git a/docs/set.md b/docs/set.md index 1524178..62071a5 100644 --- a/docs/set.md +++ b/docs/set.md @@ -1,4 +1,4 @@ -# set 命令 +# set 命令,shopt 命令 `set`命令是 Bash 脚本的重要环节,却常常被忽视,导致脚本的安全性和可维护性出问题。本章介绍`set`的基本用法,帮助你写出更安全的 Bash 脚本。 @@ -259,6 +259,57 @@ script.sh:行4: foo: 未找到命令 可以看到,`echo bar`没有执行。 +## set -E + +设置`-e`参数,会导致`trap`命令失效(参考《trap 命令》一章),`-E`参数可以纠正这个行为。 + +```bash +#!/bin/bash +set -euo pipefail + +trap "echo ERR trap fired!" ERR + +myfunc() +{ + # 'foo' 是一个不存在的命令 + foo +} + +myfunc +``` + +上面的脚本,`myfunc`函数调用了一个不存在的命令`foo`,导致执行这个函数会报错。 + +```bash +$ bash test.sh +test.sh:行9: foo:未找到命令 +``` + +但是,由于设置了`set -e`,脚本报错后并没有被`trap`命令捕获,需要加上`-E`参数才可以。 + +```bash +#!/bin/bash +set -Eeuo pipefail + +trap "echo ERR trap fired!" ERR + +myfunc() +{ + # 'foo' 是一个不存在的命令 + foo +} + +myfunc +``` + +执行上面这个脚本,就可以看到`trap`命令生效了。 + +```bash +$ bash test.sh +test.sh:行9: foo:未找到命令 +ERR trap fired! +``` + ## 其他参数 `set`命令还有一些其他参数。 @@ -271,14 +322,14 @@ script.sh:行4: foo: 未找到命令 ## set 命令总结 -上面重点介绍的`set`命令的四个参数,一般都放在一起使用。 +上面重点介绍的`set`命令的几个参数,一般都放在一起使用。 ```bash # 写法一 -set -euxo pipefail +set -Eeuxo pipefail # 写法二 -set -eux +set -Eeux set -o pipefail ``` diff --git a/docs/startup.md b/docs/startup.md index 8dbb939..ee7c630 100644 --- a/docs/startup.md +++ b/docs/startup.md @@ -90,7 +90,7 @@ $ bash --rcfile testrc - `-n`:不运行脚本,只检查是否有语法错误。 - `-v`:输出每一行语句运行结果前,会先输出该行语句。 -- `-x`:每一个命令处理完以后,先输出该命令,再进行下一个命令的处理。 +- `-x`:每一个命令处理之前,先输出该命令,再执行该命令。 ```bash $ bash -n scriptname