bash-safe

bash 脚本安全

不管是大厂还是小厂,总能听到一些误操作新闻
那避免误操作就办法就是写脚本, 然后也有很多脚本出事的新闻, 通常有以下

引用了不存在的变量

1
2
3
4
5
#!/bin/bash

ABC_PATH=abc

/bin/rm ${ABC_PATH}/

如果ABC_PATH变量被unset了, 那么就是删除系统了
不过听说/bin/rm / 的操作会可能被系统禁止, 但是/bin/rm /*则肯定能执行成功

脚本没有输出

有很多公司用堡垒机来审计操作记录, 但是如果脚本没有输出,那么就不知道执行了什么命令, 再如果脚本也被删除死无对证,那就无法分析了

解决办法

在bash 脚本前面加上 set -xeu

-x 调试模式,bash会输出所有命令
-e 遇到错误就退出
-u 引用了不存在的变量就退出

添加默认值

path=${ABC_PATH-/} #default /

这样,当ABC_PATH不存在时,就使用默认值’/‘

最好的办法

使用ansible, 可以对脚本进行版本管理和review, 可以避免脚本难以维护的问题
使用ide + bash 插件, 可以有提示

良好的脚本习惯

除了在脚本前面加上 set -xeu外, 有一些建议

  1. 多用&&,|| ,少用 ; ,如果前面的命令出错,后面就不会执行, 而; 不管
  2. 善用 date, 例如将日志文件加上日期 bash test.sh > log_date +%m_%d_%H_%M_%S``
  3. 脚本放在指定目录,不要与工作目录放在一起, 避免脚本自己被删, 死无对证
  4. 定期备份

bash 的条件判断

有以下脚本,当TMP 不为空的时候,才进行判断值是否大于2

1
2
3
4
5
6
7
8
9
10
if [ -n "$TMP" -a ${TMP} -gt 2 ];then
echo "aaaa"
else
echo "bbbbbbbb"
fi
```

而当TMP 为空的时候,就会出现 `too many arguement`。这就说明了bash的执行流程,是先进行整行替换再执行(起码是整行,也许还是全文替换)。
替换后`[-n "" -a -gt 2]`。导致了报错。
解决这样的问题可以用默认值 TMP=${TMP:=2}, 这样当TMP为空的时候就会自动赋值为2

if [ -n “$TMP” -a ${TMP:=2} -gt 2 ];then
echo “aaaa”
else
echo “bbbbbbbb”
fi