应为所有生产脚本开头添加 set -euo pipefail,用 mv -i/cp -i/rsync --dry-run 替代危险操作,通过 sudo -l/visudo 限制权限,配置 HISTTIMEFORMAT 和 sudo 日志提升可追溯性,并辅以部署前 checklist 确保环境一致性。

用 set -u 和 set -e 让 shell 脚本自动拦截常见错误
不加防护的 shell 脚本在变量未定义或命令失败时默认继续执行,极易引发级联误操作(比如删错目录、覆盖错误文件)。set -u 会在引用未声明变量时报错退出,set -e 则让任意命令非零退出码立即终止脚本。
实操建议:
- 所有生产环境脚本开头强制加上
set -euo pipefail(-o pipefail确保管道中任一环节失败都触发退出) - 临时绕过某行检查可用
command || true或set +u/set +e,但必须加注释说明原因 - 避免在
if判断中直接依赖命令返回值以外的逻辑,比如if [ -n "$var" ]; then rm -rf $dir—— 若$var为空,[ -n ]会失败,但没set -e就会静默跳过判断,直接执行rm
用 rsync --dry-run 和 mv -i 替代无脑覆盖操作
覆盖或移动文件是高频误操作场景,尤其批量处理时。Linux 原生命令默认不二次确认,而交互式开关(如 -i)和模拟执行(--dry-run)能有效拦截。
实操建议:
- 所有涉及
cp、mv、rm的脚本或命令行,优先用mv -i、cp -i;若在非交互环境(如 cron),改用rsync -av --dry-run预览变更,确认无误后再去掉--dry-run -
rsync比cp更安全:它默认不覆盖同名文件除非加--ignore-existing或--update,且能通过--delete显式控制删除行为 - 别依赖别名(如
alias rm='rm -i')—— cron 或子 shell 中别名不生效,必须显式写参数
用 sudo -l 和 visudo 限制权限粒度
给运维人员过度的 sudo 权限(如 ALL=(ALL) ALL)等于把误操作风险放大到系统级。应按最小权限原则,精确控制可执行命令与参数范围。
实操建议:
- 执行
sudo -l查看当前用户实际可用的 sudo 权限,确认是否包含高危命令(如/bin/bash、/usr/bin/vim) - 在
/etc/sudoers.d/下新建配置文件(不要直接改/etc/sudoers),用visudo -f /etc/sudoers.d/deploy编辑,例如:%deploy ALL=(www-data) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/rsync -a --delete /srv/www/ /var/www/
- 禁止通配符参数(如
/bin/rm *),改用明确路径或写 wrapper 脚本封装校验逻辑
用 history -c 和 HISTTIMEFORMAT 提升操作可追溯性
出问题后查不到谁、什么时候、执行了什么命令,是追责和复盘的最大障碍。Linux 默认 history 只记录命令文本,不带时间戳、不跨终端同步、易被清除。
实操建议:
- 在
~/.bashrc中添加:HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " export HISTCONTROL=ignoredups:ignorespace shopt -s histappend
—— 追加记录、去重、保留时间戳 - 敏感服务器上禁用
history -c,可重定向history输出到只读日志:history | tail -n 1 >> /var/log/user-commands.log - 对 root 操作,强制使用
sudo并开启Defaults logfile="/var/log/sudo.log",比直接su更易审计










