已复制
全屏展示
复制代码

linux shell 脚本 set 命令辅助


· 3 min read

set 命令可以定义脚本的运行方式、变量的获取方式、脚本的执行过程等等,在编写脚本是我们通常会使用 set 命令设置一些配置。

set -o errexit

set -e,如果脚本遇到任何错误,脚本将立即退出执行。没有使用时,脚本即使遇到错误也可以继续执行下去。

$ cat x.sh 
#!/bin/bash
set -o errexit
cat not_exists_file
echo 9

$ bash x.sh 
cat: not_exists_file: No such file or directory

set -o pipefail

需配合set -o errexit使用,表示脚本中的多管道命令运行时,如果有一个命令出现错误,脚本将会立即退出执行。

$ cat x.sh 
#!/bin/bash
set -o errexit
cat not_exists | echo 8
echo $?
echo 9

# 此时管道出现了错误,但是也会继续执行,因为管道的最后一个命令的返回值为 0
# bash 把有管道的这一行命令当成了一个完整的命令,这个完整命令的输出将从后往前:
# 即:先返回 echo 8 的输出,再返回 cat not_exists 的输出。
$ bash x.sh 
8
cat: not_exists: No such file or directory
0
9


$ cat x.sh 
#!/bin/bash
set -o errexit
set -o pipefail
cat not_exists | echo 8
echo $?
echo 9

# 此时遇到错误,脚本立即退出执行
# bash 把有管道的这一行命令当成了一个完整的命令,这个完整命令的输出将从后往前:
# 即:先返回 echo 8 的输出,再返回 cat not_exists 的输出。
$ bash x.sh 
8
cat: not_exists: No such file or directory

set -o nounset

set -u,检查脚本内的变量,如果有变量未被定义,脚本将立即退出执行。不使用时,未定义的变量会忽略这个错误。

$ cat x.sh 
#!/bin/bash
set -o nounset
echo ${a}
echo 9

$ bash x.sh 
x.sh: line 3: a: unbound variable

set -o xtrace

set -x,显示脚本执行的详细过程, set +x 关闭显示脚本执行详细过程。也就是显示脚本的 变量值。 脚本开头的 加号 个数,表示嵌套执行的深度。

  • 含义1:1个加号表示一层、2个加号表示两层、3个加号表示三层。
  • 含义2:当使用source命令时,也表示调用脚本的深度,1个加号表示当前脚本,2个加号表示当前脚本调用的另外一个脚本
$ cat x1.sh
#!/bin/bash
set -o xtrace
work_dir=$(readlink -f $(dirname $0))
if [ $# -eq 1 ]; then
  date=$1
else
  date=$(date -d "1 hour ago" "+%Y-%m-%d %H:00:00")
fi
echo "school" | awk '{print $0}'
source ./x2.sh


$ cat x2.sh
#!/bin/bash
set -o xtrace
JAVA_HOME=${work_dir}/jdk1.8
myname=$( $(which whoami) )


$ chmod +x ./x1.sh 
$ ./x1.sh 
+++ dirname ./x1.sh
++ readlink -f .
+ work_dir=/home/yzy/tmpy
+ '[' 0 -eq 1 ']'
++ date -d '1 hour ago' '+%Y-%m-%d %H:00:00'
+ date='2023-07-27 17:00:00'
+ echo school
+ awk '{print $0}'
school
+ source ./x2.sh
++ set -o xtrace
++ JAVA_HOME=/home/yzy/tmpy/jdk1.8
++++ which whoami
+++ /usr/bin/whoami
++ myname=yzy

总结

在编写脚本时最好加上这些参数,但是也要注意理解每个命令的准确含义,避免在编写脚本时造成困扰。

set -o errexit   # 遇到错误立即退出
set -o pipefail  # 管道中有命令错误则立即退出,脚本执行的退出码非零
set -o nounset   # 遇到未定义的变量立即退出
set -o xtrace    # 显示脚本执行的详细流程

在需要关闭选项时,使用 set +o 选项,比如:

set +o errexit   # 遇到错误立即退出
set +o pipefail  # 管道中有命令错误则立即退出,脚本执行的退出码非零
set +o nounset   # 遇到未定义的变量立即退出
set +o xtrace    # 显示脚本执行的详细流程
🔗

文章推荐