接触Linux已经4、5年了,也写了不少的shell脚本(虽然说都很简单),不过一直都没有写过比较大的项目,平时虽然会收集一些好的脚本,但也只是小知识点上的总结,缺少一个规范性的东西,就是“游击队”的感觉,如果再这么写下去,估计也很难成为“正规军”,水平也不会有实质性的提高,所以觉得给自己写shell脚本(以后可能还会有Python、PHP、Perl这些……)定下一个需要遵守的规范会对自己的成长有所帮助,于是就有了这篇文章。成长是一个积累的过程,愿越来越好!
写Bash脚本的一些规范小结:
0.添加 debug 标识{方便调试脚本,验证正确性}
Debug="N" mail_to="[email protected] [email protected]" [[ $Debug = 'Y' ]] && mail_to="[email protected]"
1.PATH设置
# find / -type d -iname "bin" /usr/local/bin /usr/bin /bin # find / -type d -iname "sbin" /usr/local/sbin /usr/sbin /sbin export PATH=$PATH:/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin/:/usr/local/sbin
2.脚本所在目录、脚本名称
SCRIPT_SELF_PATH="$(cd "$(dirname "$0")"; pwd)" SCRIPT_SELF_NAME="$(basename "$0")" PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path PROGDIR=`dirname $PROGNAME` # extract directory of program PROGNAME=`basename $PROGNAME` # base name of program
3.根据上一个命令的返回值打印提示消息
if [ $? -eq 0 ]; then echo "INFO|$(date +'%Y-%m-%d %H:%M:%S')|${FUNCNAME[0]}|Succeed!" else echo "ERROR|$(date +'%Y-%m-%d %H:%M:%S')|${FUNCNAME[0]}|Failed!" return 1 fi
4.文件[夹]不存在则新建
result_path="/root/tmp/result" if [ ! -d "$result_path"]; then mkdir -p "$result_path" fi
或
result_path="${HOME}/hostsList" [ -d "$result_path" ] || mkdir -p "$result_path"
5.计算脚本的执行消耗时间
function func_show_cost_time() { local cost_all="$SECONDS" local cost_h=$((cost_all/3600)) local cost_m=$((cost_all%3600/60)) local cost_s=$((cost_all%60)) echo "INFO|cost|$cost_all|$cost_h:$cost_m:$cost_s" }
6.某一字符集的for循环
items="0123456789abcdefghijklmnopqrstuvwxyz" i="" for ((i=0;;i++)); do item=${items:$i:1} if [ -z "$item" ]; then break fi echo $item # Put command here if [ $? -ne 0 ]; then echo "ERROR|command execute failed" exit 1 else echo "INFO|command execute succeed" fi done
7.某些直接命令的使用
pgrep readlink exec_user=$(ps -o user --no-headers "$pid")
8.跳过空行/注释行
cat file.conf | grep -Ev "(^$|^#$)"
9.防止因为权限不够导致的错误
tmp=$(cat /etc/rsyslog.conf 2>/dev/null || sudo cat /etc/rsyslog.conf 2>/dev/null)
10.用test命令简化脚本
test "$cc" == "163_box" && echo "$notice_type" | grep -q "alert" test $? -eq 0 && mail_cc="${mail_cc},[email protected]" # http://www.ict.griffith.edu.au/anthony/info/shell/script.hints
11.根据文件的新旧程度移动到指定位置
tmp_file=$(mktemp -p ${HOME}) tmp_time=$(date -d "-2 days" +'%Y-%m-%d 00:00:05') touch -d "$tmp_time" "$tmp_file" find ${HOME} -maxdepth 1 -type f -iname "${HOSTNAME}*.txt" ! -newer "$tmp_file" -print0 | xargs -0 -I {} mv {} ${result_path} rm -f $tmp_file
12.shell脚本在执行失败时立即退出
搜索关键字:
- linux bash script exit on error
参考链接:
- http://stackoverflow.com/questions/1378274/in-a-bash-script-how-can-i-exit-the-entire-script-if-a-certain-condition-occurs
- http://stackoverflow.com/questions/2870992/automatic-exit-from-bash-shell-script-on-error
参考解答:
set -e #add this to the second line of the bash script exit 0/1/2/... bash -e script_name.sh
=待续=
《 “写Bash脚本的一些规范小结” 》 有 4 条评论
bats-Bash自动化测试工具
https://mp.weixin.qq.com/s/14q8I-rmpbSLVlD_n0noQg
https://github.com/bats-core/bats-core
https://github.com/bats-core/bats-core/wiki/Syntax-Highlighting
https://github.com/sstephenson/bats/wiki/Bats-Evaluation-Process
编写可靠 bash 脚本的一些技巧
https://mp.weixin.qq.com/s/VmM_U4RefRBHwIw8NegC8Q
`
写过很多 bash 脚本的人都知道,bash 的坑不是一般的多。其实 bash 本身并不是一个很严谨的语言,但是很多时候也不得不用。以下总结了一些编写可靠的 bash 脚本的小 tips。
0. set -x -e -u -o pipefail
在写脚本时,在一开始(Shebang 之后)加上下面这一句,或者它的缩略版,能避免很多问题,更重要的是能让很多隐藏的问题暴露出来:
set -xeuo pipefail
1. 防止重叠运行
在一些场景中,我们通常不希望一个脚本有多个实例在同时运行。比如用 crontab 周期性运行脚本时,有时不希望上一个轮次还没运行完,下一个轮次就开始运行了。这时可以用 flock 命令来解决。flock 通过文件锁的方式来保证独占运行,并且还有一个好处是进程退出时,文件锁也会自动释放,不需要额外处理。
2. 意外退出时杀掉所有子进程
我们的脚本通常会启动好多子脚本和子进程,当父脚本意外退出时,子进程其实并不会退出,而是继续运行着。如果脚本是周期性运行的,有可能发生一些意想不到的问题。
3. timeout 限制运行时间
4. 连续管道时,考虑使用 tee 将中间结果落盘,以便查问题
`
Bash 教程
https://wangdoc.com/bash/
https://github.com/wangdoc/bash-tutorial
7 个 Bash 教程,提高你的命令行技能(2021 版)
https://linux.cn/article-13090-1.html
[1]: https://linux.cn/article-12385-1.html
[2]: https://opensource.com/article/20/4/bash-sysadmins-ebook
[3]: https://linux.cn/article-12025-1.html
[4]: https://opensource.com/article/20/1/screenfetch-neofetch
[5]: https://linux.cn/article-11797-1.html
[6]: https://opensource.com/article/20/1/improve-bash-scripts
[7]: https://linux.cn/article-11841-1.html
[8]: https://opensource.com/users/jim-hall
[9]: https://github.com/lujun9972
[10]: https://github.com/Chao-zhi
[11]: https://github.com/wxy
[12]: https://github.com/LCTT/TranslateProject
via: https://opensource.com/article/21/1/bash