应让脚本以 root 权限运行但备份文件归属普通用户,通过权限分离实现:root 执行高权限操作(如 mysqldump),再用 sudo -u user 显式降权写入;需配置 sudoers 免密并限定命令范围。

让定时备份脚本以 root 权限运行(比如访问系统级数据库、读取 /etc 或 /var/lib/mysql 等受保护路径),同时确保生成的备份文件归普通用户所有,关键在于“权限分离”——不是用 root 身份全程执行并留下 root 所属文件,而是只在必要环节提权,其余操作回落到目标用户上下文。
明确区分执行权限与文件归属
root 运行脚本 ≠ 备份文件必须属 root。Linux 文件归属由创建进程的有效 UID 决定,而创建行为可发生在非 root 环境下。常见误区是直接用 root 执行整个脚本,结果所有输出文件自动归 root,后续普通用户无法直接读写或清理。
- 脚本本身由 root 执行(满足高权限读取需求)
- 但关键输出步骤(如重定向写入、tar 打包、mysqldump 输出)应显式指定目标用户上下文
- 避免用
> backup.sql这类裸重定向——它继承当前进程 UID(即 root),改用sudo -u user1 tee backup.sql > /dev/null或提前切换目录并设置 umask + setgid
推荐做法:root 执行 + sudo 切换用户写入
在脚本中,对需要 root 权限的操作(如 mysqldump、读取 /etc/crontab)保留 root 上下文;对写入备份文件的动作,用 sudo -u username 显式降权:
mysqldump -u root -p'xxx' dbname | sudo -u backupuser tee "/home/backupuser/backups/db_$(date +%Y%m%d).sql" > /dev/null- 或分步:先 dump 到临时 root 可写位置(如
/tmp/db.tmp),再sudo -u backupuser cp /tmp/db.tmp /home/backupuser/backups/,最后rm /tmp/db.tmp - 确保
backupuser对目标目录有写权限:chown backupuser:backupuser /home/backupuser/backups,且目录权限为755或775(若需组协作)
配合 crontab 安全调用
不要把脚本直接放进 root 的 crontab 后放任它全权操作。更稳妥的方式是:
- 将脚本放在安全路径(如
/usr/local/bin/backup-db.sh),属主设为 root:root,权限755 - 在 root 的 crontab 中调用:
0 2 * * * /usr/local/bin/backup-db.sh - 脚本开头加
#!/bin/bash,不依赖用户环境变量;必要时source /etc/profile或硬编码 PATH - 所有外部命令(如 mysqldump、tar、gzip)使用绝对路径,避免 crontab 默认 PATH 不足导致失败
补充:避免 sudo 密码提示的配置
若脚本内多次调用 sudo -u backupuser,需免密配置。编辑 /etc/sudoers(务必用 visudo):
- 添加一行:
root ALL=(backupuser) NOPASSWD: /bin/cp, /usr/bin/tee, /bin/mv - 限制仅允许特定命令,不开放
ALL,防止滥用 - 验证方式:
sudo -u backupuser -n ls /home/backupuser(-n表示不提示密码)

















