# backup.sh 把指定目录打包成 `tar.gz`,再通过 SMB / Samba 上传到远端服务器。同时支持 **Linux** 与 **macOS**。 > SFTP 等其它方式已在脚本中预留入口(`run_sftp`、`SFTP_*` 配置),目前未实现。 ## 系统要求 - bash 3.2+ / tar / date - Linux:`smbclient`(包含在 `smbclient` 或 `samba-client` 包中) - macOS:`smbclient`(推荐,`brew install samba`),或退回到系统自带的 `mount_smbfs` ### 安装依赖 | 系统 | 命令 | | --- | --- | | Debian / Ubuntu | `apt install -y smbclient` | | RHEL / Rocky / Alma | `dnf install -y samba-client` | | Arch | `pacman -S smbclient` | | macOS | `brew install samba`(可选,无则使用 `mount_smbfs`) | ## 文件 ``` backup/ ├── backup.sh # 主脚本 ├── backup.conf # 配置文件(与脚本同目录) └── README.md ``` ## 下载到本地 为避免后续脚本更新导致 `bash <(curl ...)` 形式的执行失效(参数变化、行为不兼容等),建议先下载到本地再执行: ```bash # 创建目录并下载脚本与示例配置 mkdir -p ~/backup && cd ~/backup curl -fsSL -o backup.sh https://git.suhang.me/suhang/scripts/raw/branch/release/backup/backup.sh curl -fsSL -o backup.conf https://git.suhang.me/suhang/scripts/raw/branch/release/backup/backup.conf chmod +x backup.sh chmod 600 backup.conf # 编辑 backup.conf 后执行 bash backup.sh smb ``` 也可改用 `wget`: ```bash wget -qO backup.sh https://git.suhang.me/suhang/scripts/raw/branch/release/backup/backup.sh wget -qO backup.conf https://git.suhang.me/suhang/scripts/raw/branch/release/backup/backup.conf ``` ## 使用方式 ```bash bash backup.sh [options] ``` `method` 取值: | 方式 | 说明 | | --- | --- | | `smb` | 通过 SMB / Samba 上传 | | `sftp` | 已预留入口,暂未实现 | 最常见的用法是先编辑同目录下的 `backup.conf`,然后执行: ```bash bash backup.sh smb ``` ## 配置文件 `backup.conf` 脚本默认读取 **脚本所在目录** 下的 `backup.conf`,可用 `-C` / `--config` 指定其它路径。 | 字段 | 说明 | | --- | --- | | `SOURCE_PATHS` | 要备份的源路径,多个用空格分隔,需引号包裹 | | `TMP_DIR` | 本地临时打包目录,默认 `/tmp/backup` | | `ARCHIVE_PREFIX` | 归档文件名前缀,最终形如 `prefix-YYYYmmdd-HHMMSS.tar.gz` | | `METHOD` | 默认上传方式(`smb` / `sftp`),命令行参数会覆盖 | | `CLEAN_LOCAL` | 上传后是否删除本地归档(`true` / `false`) | | `RETENTION_DAYS` | 远端保留天数,`0` 表示不清理 | | `SMB_HOST` | SMB 服务器地址 | | `SMB_SHARE` | 共享名 | | `SMB_PATH` | 共享内的子目录(可选) | | `SMB_USER` / `SMB_PASSWORD` | 凭据 | | `SMB_DOMAIN` | 域 / 工作组(可选) | | `SMB_VERSION` | SMB 协议版本,如 `3.0`(可选) | | `SFTP_*` | 预留字段,目前未启用 | ## 命令行参数 所有 `backup.conf` 中的字段均可通过命令行参数覆盖;命令行参数优先级最高。 ### 通用 | 参数 | 对应配置 | | --- | --- | | `-C, --config FILE` | 指定配置文件路径 | | `-s, --source "P1 P2"` | `SOURCE_PATHS` | | `-t, --tmp-dir DIR` | `TMP_DIR` | | `-p, --prefix NAME` | `ARCHIVE_PREFIX` | | `--keep-local` | 等价于 `CLEAN_LOCAL=false` | | `--retention DAYS` | `RETENTION_DAYS` | | `-h, --help` | 显示帮助 | ### SMB | 参数 | 对应配置 | | --- | --- | | `--smb-host HOST` | `SMB_HOST` | | `--smb-share NAME` | `SMB_SHARE` | | `--smb-path PATH` | `SMB_PATH` | | `--smb-user USER` | `SMB_USER` | | `--smb-password PASS` | `SMB_PASSWORD` | | `--smb-domain DOMAIN` | `SMB_DOMAIN` | | `--smb-version VER` | `SMB_VERSION` | ### SFTP(预留) `--sftp-host` `--sftp-port` `--sftp-user` `--sftp-password` `--sftp-key` `--sftp-path` ## 示例 完全依赖配置文件: ```bash bash backup.sh smb ``` 只用命令行参数(不依赖 `backup.conf`): ```bash bash backup.sh smb \ -s "/etc /var/log /home/user/data" \ --smb-host 192.168.1.10 \ --smb-share backup \ --smb-path servers/web1 \ --smb-user backup \ --smb-password 'P@ssw0rd' \ --retention 30 ``` 混合使用(基础信息读 `backup.conf`,源路径临时覆盖): ```bash bash backup.sh smb -s "/var/lib/mysql" ``` ## 定时任务 使用 `>`(单箭头)覆盖写入日志,避免日志文件无限增长——只保留最近一次执行的日志: ```cron # 每天 03:10 跑一次 10 3 * * * /bin/bash /path/to/backup/backup.sh smb > /var/log/backup.log 2>&1 # 每天 03:17 跑一次 17 3 * * * /bin/bash /path/to/backup/backup.sh smb > /var/log/backup.log 2>&1 ``` > 如果有多条任务都写到同一个日志文件,请改用不同的日志路径(例如 `/var/log/backup-0310.log`、`/var/log/backup-0317.log`),否则后一次会覆盖前一次。 macOS 可用 `launchd` 或 `cron`(需要在「系统设置 → 隐私与安全性 → 完全磁盘访问权限」中授予 `cron` 权限以读取受保护目录)。 ## 路径与文件 | 路径 | 说明 | | --- | --- | | `${TMP_DIR}/${ARCHIVE_PREFIX}-YYYYmmdd-HHMMSS.tar.gz` | 本地临时归档(默认上传后删除) | | 远端 `//${SMB_HOST}/${SMB_SHARE}/${SMB_PATH}/` | 上传目标目录 | ## 注意事项 - 命令行密码会出现在进程列表中,安全敏感场景请优先使用 `backup.conf`,并把权限收紧:`chmod 600 backup.conf`。 - macOS 上若未安装 `smbclient`,会回退到挂载方式(`mount_smbfs`),此时不支持 `--retention` 远端清理,仅完成上传。 - 远端清理仅清理符合 `${ARCHIVE_PREFIX}-YYYYmmdd-HHMMSS.tar.gz` 命名规范的文件,避免误删其它内容。