shell脚本 注意事项

规范类shell编写

1.脚本开头部分应有脚本功能说明,参数使用说明,作者姓名,创建/修改日期,版本信息

2.脚本编写时。注意格式对齐。例如循环或判断语句前后的语句进行对齐,以及选取完全。

3.脚本开头执行时,执行(如set -eu或 set -euo pipefail)在执行过程中遇到了使用了未定义的变量或命令返回值为非零,将直接报错退出

4.建议将命令行的每个参数放在单/双引号中,特别是rm、mv等可能对生产现有数据造成修改的操作,建议使用垃圾邮箱策略:rm操作转意为mv操作,制定文件保存目录,以防回退,并定期清理

rm -r "$APPPATH/20191118"

rm -r "/app/data/20191118"

mv "$LOGPATH/20191118.tar"  "$LOGBAKPATH"

5.命令行中参数需要使用‘*’ 、' ?' 通配符的,应依据最精确匹配原则,可以确定文件、目录名称的前缀、后缀、扩展名及其他可能识别关键字的,必须在参数中包含该信息,如能确定文件、目录的长度应使用“?”通配符,不得使用‘*’。

6.给数值型变量的赋值后,需由手段保证变量的值为数值型,避免在后续的处理中出现异常

count='cat app.log | wc -l`

isNumber $count

isNumber()

{

if [ "$1" -eq "$1" ];then true

else

    echo "[$1] isn't a number"

    exit 1

fi

7.在判断条件中使用的变量,必须包含在双引号中;如 if [ "$i" -lt "max" ]

8.对文件进行打包备份时,必须使用相对路径进行打包,严禁将全路径打入tar包(小编表示疑惑???)

9.对于打包后还需要进行压缩的文件,建议使用管道进行处理,

如 cd /appdata.log  && tar cvf - ”20191118“ | compress -c 20191118.tar.Z

不建议两部分分开执行(cd /app/data/log && tar cvf "20191118.tar' '20191118' compress 20191118.tar)

10.使用ps命令筛选进程时,如能确定进程所属用户,必须在参数中指定用户名称,如其输出作为kill命令输入,则必须指定进程所属用户,如 kill -9 `ps -fu $USERNAME | grep java | grep AdminServer `

易错类shell编写

1.更新文件使用 > 不用cp,使用> 修改和回退文件时,保留原文件的属组和权限,避免使用cp时权限属组被修改

2.使用kill前确认,关键字用 -w精确匹配;kill前后都保留现场,两次ps -ef | grep -w 关键字 | grep -v grep >> /tmp/kill_进程名.backup';删除前要校验,获取进程号是否唯一,避免多杀误杀情况

3.使用rm前确认

删除前备份删除对象信息,避免使用变量,直接使用文件和目录名;如必须使用时,请删除前检查,删除目录和文件信息保留

4.for循环的坑,for循环的in条件按空格来区分,避免不正确或者死循环

5.while循环的禁忌;如果还想使用循环中的变量。不要使用while结合管道使用

6.慎用cp,同样有空格之分,应当使用双引号,如凑巧以-开头,这个文件名会被cp当做命令行来处理

7.慎用cd,避免使用cd到操作目录在操作的方式,可能导致进入目录失败,误删除,如:

cd /app/logbak ;   rm 20????.tar

建议: rm '/app/logbak/201911.tar'  ;    mv '~/log/201911.tar' ~/logbak

8用[[ ]]代替[ ]

例:[ $var = "var" ]

当$var为空,上面就变成了 [ = "var" ]

类似的,当$var包含空格时  [space words here = "var" ]两者都报错,应当用双引号将变量括起来

但是当$var 以- 开头时依然有问题,在较新的bash中,可以使用 [[$var = var]],  [[]]能正确处理空白空格横线等问题

9.管道操作中不要同时读写文件,不能在同一条管道操作中同时读写一个文件,根据管道的实现方式,file要么被截断成0字节要么会无限增长直到填满整个硬盘,如想改变原文件内容只能先将输出写道临时文件再用mv命令

10.cd易错问题,可能会导致执行的命令就会在你预想不到的目录里执行了

所以一定要记得判断cd的返回值。cd /dir && test

可以用||根据cd的返回值执行多条命令。 cd /dir || exit 1; test

例如: find ... -type d | while read subdir; do cd "$subdir" && ...&& cd -done

换成:find ... -type d | while read subdir; do (cd "$subdir"&& ...&& ...)done

&& ...)done && ...) done & ...)done

cd -done

括号会强制启动一个子shell,这样在这个子shell中改变工作目录不会影响父shell(执行这个脚本的shell),

就可以省掉cd - 的麻烦。

应用类shell编写

1.交互式脚本的应用,脚本中需要进行交互,使用expect

也可以使用curl工具代替简单的交互

下载:curl -u ftpuser:ftppassword -O "sftp://ftp_ip:ftp_port/pathfile"

上传:curl -u ftpuser:ftppassword --ftp-create-dirs-T upfile "sftp://ftp_ip:ftp_port/filrpath/upfile"

2.脚本规范执行和日志追溯。直接执行脚本很危险,要提示用户如何使用脚本,并记录日志以便跟踪。

3.脚本的并发锁控制。避免多人同时执行或并发同时执行的异常问题。建议增加锁机制。

4.控制脚本不退出的风险。周期频繁执行的脚本,需防止脚本hang住不退出,导致后续脚本再次执行

5.避免集中发布脚本造成风险。使用ftp、sftp传输、下载文件,或集中访问存储端口时,尽量增加发布对象散列,避免集中操作造成存储端口拥挤,跨防火墙流量超限报警等影响。

6.避免文件无线增长的风险

向一个文件追加数据时,一定要设置阀值,必要时清空,避免文件无线增大。

目录增加清理过期文件策略,避免产生的文件越来越多,造成文件节点用尽。

目录中的文件过多,会报参数太长错误无法删除,建议放循环中遍历删除

一、通过规范类脚本的定义,标准常量定义,清晰的注释、函数和变量大小写用法!

二、通过易错类脚本中的‘坑’,是的shell面向过程的编写更得心应手。让脚本规范同时逻辑也严谨清晰,避免了错误。

三、通过运维场景脚本应用,规避各种开发和执行过程中的风险,使脚本支持自动化发布,更全面智能化的为运维服务。

发布了67 篇原创文章 · 获赞 13 · 访问量 4067

猜你喜欢

转载自blog.csdn.net/tongzhuo1220/article/details/103117985