015 Linux Shell 入门教程(十五):Shell 脚本安全性与最佳实践
本章目标:避免脚本误操作或安全漏洞,写出健壮、可信赖的 Shell 工具。
一、为何脚本安全重要?
Shell 脚本可执行任意系统命令,稍有疏忽可能导致:
- 文件误删
- 权限泄露
- 命令注入
- 数据丢失
- 被恶意利用
因此,在开发和使用脚本时,应严格遵循安全与规范实践。
二、防止误删:危险命令加保险
1. 明确判断再执行
if [[ -d "$target_dir" && "$target_dir" != "/" ]]; then
rm -rf "$target_dir"
fi
禁止对空变量或根目录操作。
2. 使用 -i提示确认
rm -i "$filename"
三、变量处理防注入
1. 用双引号包裹变量
错误示例:
rm -rf $user_input
当 user_input 为 "/ important",后果灾难性!
安全示例:
rm -rf "$user_input"
四、防止命令注入
用户传参中混入恶意代码,如:
name="abc; rm -rf /"
eval "echo Hello $name"
尽量避免使用 eval
若必须执行动态命令,需过滤参数或改用安全方法(数组或 case)。
五、限制权限和执行来源
1. 设置脚本权限
chmod 700 your_script.sh
仅允许拥有者执行,防止被他人篡改或误用。
2. 不在全局路径中放自定义脚本
建议放入 ~/bin/ 并添加到 $PATH。
六、使用 set防御常见错误
set -euo pipefail
参数 | 说明 |
-e | 命令出错立即退出 |
-u | 未定义变量时报错 |
-o pipefail | 管道中任一命令失败则整个失败 |
七、安全读取用户输入
避免直接使用 read 输入执行命令:
read -p "请输入文档名:" filename
cat "$filename"
加入文件存在性检查:
if [[ -f "$filename" ]]; then
cat "$filename"
else
echo "文档不存在!"
fi
八、敏感信息保护
- 不在脚本中明文写密码或 token
- 使用环境变量或 .env 文件 + .gitignore
- 加密配置文件(如 gpg、age)
九、审查外部命令依赖
1. 检查命令是否存在
command -v curl >/dev/null || {
echo "curl 未安装"
exit 1
}
2. 限制可执行范围(白名单法)
case "$action" in
start|stop|restart) ;;
*) echo "无效操作"; exit 1 ;;
esac
十、日志与审计建议
- 所有操作记录日志
- 关键操作前后打印状态
- 失败时输出错误信息并退出
log() {
echo "[$(date '+%F %T')] $1" >> /var/log/myscript.log
}
Shell 安全实践清单
建议 | 示例或理由 |
避免 eval | 防注入风险 |
所有变量加引号 | 防止空格截断或注入 |
使用 set -euo pipefail | 保证错误立即退出 |
使用 command -v 检查依赖 | 保证可复用和移植 |
避免脚本中写明密码 | 用 .env、read -s 代替 |
使用 chmod 700 控制权限 | 防止脚本被篡改 |
日志记录每步关键操作 | 审计和回溯用 |
下一篇预告:
Linux Shell 入门教程(十六):用 Shell 构建自动化运维工具(实战)
将用一个实际工具项目,整合前 15 章知识,完成一个自动部署+告警+备份的综合脚本。