Shell 脚本零碎笔记
set的基本用法,写出更安全的 Bash 脚本
set -u
: 脚本在头部加上它,遇到不存在的变量就会报错,并停止执行set -x
: 用来在运行结果之前,先输出执行的那一行命set -e
: 它使得脚本只要发生错误,就终止执行
某些命令的非零返回值可能不表示失败,或者开发者希望在命令失败的情况下,脚本继续执行下去。这时可以暂时关闭set +e
,该命令执行结束后,再重新打开set -e
还有一种方法是使用command || true
,使得该命令即使执行失败,脚本也不会终止执行
set -e
有一个例外情况,就是不适用于管道命令,此时需要用到下面用法set -o pipefail
只要一个子命令失败,整个管道命令就失败,脚本就会终止执行set -n
: 等同于set -o noexec
,不运行命令,只检查语法是否正确。set -f
: 等同于set -o noglob
,表示不对通配符进行文件名扩展。set -v
: 等同于set -o verbose
,表示打印 Shell 接收到的每一行输入
总结
重点介绍的set
命令的四个参数,一般都放在一起使用
1 | 写法一 |
这两种写法建议放在所有 Bash 脚本的头部
另一种办法是在执行 Bash 脚本的时候,从命令行传入这些参数
Bash 脚本除错
在使用脚本删除某个目录文件时:
尽量使用下面的写法
1 | [[ -d $dir_name ]] && cd $dir_name && rm * |
上面代码中,先判断目录$dir_name
是否存在,然后才执行其他操作
如果不放心删除什么文件,可以先打印出来看一下
1 | [[ -d $dir_name ]] && cd $dir_name && echo rm * |
上面命令中,echo rm *
不会删除文件,只会打印出来要删除的文件
mktemp 命令,trap 命令
生成临时文件应该遵循下面的规则:
- 创建前检查文件是否已经存在
- 确保临时文件已成功创建
- 临时文件必须有权限的限制
- 临时文件要使用不可预测的文件名
- 脚本退出时,要删除临时文件(使用 trap 命令)
mktemp 命令
Bash 脚本使用mktemp命令的用法如下
1 | !/bin/bash |
为了确保临时文件创建成功,mktemp
命令后面最好使用 OR
运算符(||
),保证创建失败时退出脚本
1 | !/bin/bash |
为了保证脚本退出时临时文件被删除,可以使用trap
命令指定退出时的清除操作
1 | !/bin/bash |
-d
: 可以创建一个临时目录-p
: 可以指定临时文件所在的目录-t
: 可以指定临时文件的文件名模板,模板的末尾必须至少包含三个连续的X
字符,表示随机字符,建议至少使用六个X
,默认的文件名模板是tmp.后接十个随机字符
1 | >$ mktemp -t mytemp.XXXXXXX |
trap 命令
trap
命令用来在 Bash 脚本中响应系统信号,命令格式如下
1 | >$ trap [动作] [信号1] [信号2] ... |
“动作”是一个 Bash 命令,“信号”常用的有以下几个
- HUP:编号1,脚本与所在的终端脱离联系。
- INT:编号2,用户按下 Ctrl + C,意图让脚本中止运行。
- QUIT:编号3,用户按下 Ctrl + 斜杠,意图退出脚本。
- KILL:编号9,该信号用于杀死进程。
- TERM:编号15,这是kill命令发出的默认信号。
- EXIT:编号0,这不是系统信号,而是 Bash 脚本特有的信号,不管什么情况,只要退出脚本就会产生。
trap
命令响应EXIT
信号的写法如下:
1 | >$ trap 'rm -f "$TMPFILE"' EXIT |
上面命令中,脚本遇到EXIT
信号时,就会执行rm -f "$TMPFILE"
trap 命令的常见使用场景,就是在 Bash 脚本中指定退出时执行的清理命令
注意,trap命令必须放在脚本的开头。否则,它上方的任何命令导致脚本退出,都不会被它捕获
如果trap需要触发多条命令,可以封装一个 Bash 函数
1 | function egress { |
为了方便 Debug,有时在启动 Bash 的时候,可以加上启动参数
-n
:不运行脚本,只检查是否有语法错误-v
:输出每一行语句运行结果前,会先输出该行语句-x
:每一个命令处理完以后,先输出该命令,再进行下一个命令的处理
使用下面的代码,可以设定其后文本的颜色:
\033[0;30m
:黑色\033[1;30m
:深灰色\033[0;31m
:红色\033[1;31m
:浅红色\033[0;32m
:绿色\033[1;32m
:浅绿色\033[0;33m
:棕色\033[1;33m
:黄色\033[0;34m
:蓝色\033[1;34m
:浅蓝色\033[0;35m
:粉红\033[1;35m
:浅粉色\033[0;36m
:青色\033[1;36m
:浅青色\033[0;37m
:浅灰色\033[1;37m
:白色
除了设置前景颜色,Bash 还允许设置背景颜色:
\033[0;40m
: 蓝色\033[1;44m
: 黑色\033[0;41m
: 红色\033[1;45m
: 粉色\033[0;42m
: 绿色\033[1;46m
:青色\033[0;43m
:棕色\033[1;47m
:浅灰色