把 Windows SMB(共享 SSD)当作 Time Machine 备份盘

场景:把 macOS(你已配置好的系统)完整备份到挂在局域网/Windows 上的共享 SSD(SMB),用 sparsebundle 做容器,最后让 Time Machine 认到并自动备份。
命令行的实操(scutilifconfighdiutiltmutil)和遇到的权限问题(Terminal 需要 Full Disk Access)都整合进来,并附上常见问题与解决办法、以及一个一键脚本(可直接复制粘贴运行)。


摘要(为什么用 sparsebundle)

  • 网络备份(NAS / 共享盘)上的 Time Machine 实际上存放在一个 .sparsebundle(可动态增长的磁盘镜像)里,macOS 会把 Time Machine 的目录结构放到这个镜像内。网络备份可以走 SMB(前提:NAS/服务器支持 Time Machine over SMB / 或者你用 sparsebundle 存放在普通可写的 SMB 共享上)。(Apple Support)

前置条件

  1. Windows 共享(SMB)已经创建并在网络可达,且你的 mac 有读写权限。
  2. 建议共享盘容量 >= 你计划给备份的上限(例如你想 100GB 上限,就保证共享盘至少有 100GB 可用)。
  3. 在 mac 上给 Terminal(或你要运行脚本的终端 app)授予「完全磁盘访问(Full Disk Access)」,否则 tmutil 某些命令会被拒绝(后面有具体步骤)。(Apple Support)

实操(示例)

命令/输出(作为示例):

# 电脑名
scutil --get ComputerName
# MyMacPro

# Wi-Fi / 网卡 MAC
ifconfig en0 | grep ether
# ether a1:b2:c3:d4:e5:f6

# 创建 sparsebundle(你用的命令)
hdiutil create -size 600G -type SPARSEBUNDLE -fs "Case-sensitive Journaled HFS+" -volname "TimeMachine" "/Volumes/WinShare/mactime/MyMacPro_a1b2c3d4e5f6.sparsebundle"
# created: /Volumes/WinShare/mactime/MyMacPro_a1b2c3d4e5f6.sparsebundle

# 挂载后(双击 sparsebundle) -> 再设置 Time Machine 目的地
sudo tmutil setdestination /Volumes/TimeMachine
# (需要 Terminal 的 Full Disk Access,授予后执行成功)

详细步骤(从零到可以被 Time Machine 识别并备份)

1) 在 Finder 挂载 Windows 共享(推荐 GUI)

Finder → 前往 → 连接服务器(⌘K),填写:

smb://<Windows-IP-or-hostname>/<share-name>

输入用户名/密码,确认可读写。确认挂载点(比如:/Volumes/WinShare)。

(也可以用 mount_smbfs 命令行挂载,但 GUI 最简单)(Apple Support)


2) 获取 ComputerName 与 MAC(用于 sparsebundle 命名)

Time Machine 的网络 sparsebundle 通常用 <ComputerName>_<MAC-without-colons>.sparsebundle 命名(这能让服务器区分多台机器的备份)。

命令:

# ComputerName
scutil --get ComputerName

# 获取默认出口网卡并读 MAC
IFACE=$(route get default 2>/dev/null | awk '/interface:/{print $2}'); [ -z "$IFACE" ] && IFACE=en0
MAC=$(ifconfig "$IFACE" | awk '/ether/{print $2}' | sed 's/://g')
echo "iface=$IFACE mac=$MAC"

示例结果(你的环境):

ComputerName = MyMacPro
MAC = a1b2c3d4e5f6

3) 在共享盘上创建 sparsebundle(两种策略)

优先策略 A:直接在已挂载的 SMB 共享上创建(你已经成功)

hdiutil create -size 100G -type SPARSEBUNDLE \
  -fs "Case-sensitive Journaled HFS+" \
  -volname "TimeMachine" \
  "/Volumes/WinShare/mactime/MyMacPro_a1b2c3d4e5f6.sparsebundle"

说明:-size 100G 是镜像的最大容量,但 sparsebundle 是“动态增长”的,刚创建不会立刻占满物理空间。推荐去 system settings/general/storage 看看当前的 storage 占用, 然后设置一个合理的大小.

备用策略 B(若直接在 SMB 上创建超时失败):先在本地创建,再拷贝到 SMB(某些 SMB 实现或网络环境下 hdiutil create 直接在 SMB 上可能超时失败)。这类问题在实践里有报告(如果遇到 create 超时,尝试本地创建再搬运)。(Ask Different)


4) 挂载 sparsebundle(双击或命令行)

双击 Finder 中的 .sparsebundle,或命令行:

hdiutil attach "/Volumes/WinShare/mactime/MyMacPro_a1b2c3d4e5f6.sparsebundle"
# 之后查看 /Volumes 下挂载的卷名
ls /Volumes

通常会以 TimeMachine(或你在 -volname 指定的名字)挂载为 /Volumes/TimeMachine。(Stephen Foskett, Pack Rat)


5) 让 Time Machine 使用该挂载卷(关键)

GUI 有时候不把挂载的镜像列出来,最稳妥的方式是用 tmutil 命令设置目的地:

重要:在运行下面命令之前,请先给 Terminal(或你要用的终端)授予「完全磁盘访问(Full Disk Access)」权限(否则 tmutil 会提示权限错误)。授予方法:系统设置 → 隐私与安全 → 隐私 → Full Disk Access → 加入 Terminal。详见 Apple 指南。(Apple Support)

设置命令:

sudo tmutil setdestination "/Volumes/TimeMachine"
# 验证
tmutil destinationinfo
====================================================
Name          : TimeMachine
Kind          : Local
ID            : DF0ACC60-111D-4764-A023-C2FBE09176FE

如果你想立刻触发一次备份(手动):

tmutil startbackup --auto
# 或者手动选择要 backup 到的 disk: tmutil startbackup --destination [DISK_ID]
# [DISK_ID] 可以通过 tmutil destinationinfo 来获得, 比如: DF0ACC60-111D-4764-A023-C2FBE09176FE
# 或加 --block 等选项根据需要(见 man tmutil)

tmutil 是 Time Machine 的命令行工具,可以查询/设置目的地、强制备份、查看备份列表等。(SS64)


常见问题与排错(你可能会遇到的)

Q1 — 双击挂载了 sparsebundle,却在 Time Machine 偏好里看不到它 / 列表为空

  • 可能需要用 sudo tmutil setdestination /Volumes/TimeMachine 手动把挂载点设为备份目的地(如上)。
  • GUI 列表主要显示“系统能识别的备份目标”,自建 sparsebundle 常需要 tmutil 明确设置。(Apple Support)

Q2 — tmutil 报错 requires Full Disk Access / 无法运行

  • 去 系统设置 → 隐私与安全 → 隐私 → 完全磁盘访问(Full Disk Access),把 Terminal(或你运行脚本的终端应用)加入白名单,然后重启 Terminal 后再执行命令。某些 tmutil 的动作(如列出备份、setdestination)即使用 sudo 也需要这个权限。(Apple Support)

Q3 — hdiutil create 在 SMB 上失败 / 超时

  • 某些 SMB 服务器在创建大镜像时会超时或挂起(尤其是 Windows/Samba 不完全兼容或网络不稳定时)。解决办法:先在本地创建 .sparsebundle~/Desktop),确认 OK,再拷贝到 SMB;或在服务器端直接创建(如果可行)。(Ask Different)

Q4 — 我应该用 HFS+ 还是 APFS 做 sparsebundle 的内部文件系统?

  • 传统上网络 sparsebundle 常用 Case-sensitive Journaled HFS+(Mac OS 扩展),兼容性最广;近年来 APFS sparsebundle 在某些场景下也能工作,但网络断连/兼容性问题在少数环境仍存在差异。一般建议用 HFS+(Case-sensitive Journaled HFS+)以提高兼容性,除非你有特别原因要用 APFS。(Ask Different)

Q5 — 如何回收 sparsebundle 中已删除的空间?

  • 可以使用 hdiutil compact /path/to/your.sparsebundle 来回收未使用的 band,但 compact 有时对网络卷和某些配置会失败(在执行前确保镜像已卸载或正确挂载,并接通电源以免被系统限制)。(Stephen Foskett, Pack Rat)

Q6 — 如何取消管理 Time Machine 中的 sparsebundle 呢?

  • 可以使用 sudo tmutil removedestination <ID> 来取消 Time Machine 对其的显示和管理

一键自动化脚本(示例,Bash)

脚本功能:读取 ComputerName、网卡 MAC,拼出 sparsebundle 名称,创建在指定挂载路径(你需先手动挂载 SMB 共享),挂载后把它设置为 Time Machine 目标。运行前请先给 Terminal 完全磁盘访问权限。

把下面内容保存为 create_tm_smb.sh,并 chmod +x create_tm_smb.sh

#!/usr/bin/env bash
set -euo pipefail

# usage: ./create_tm_smb.sh /Volumes/YourShare/path 600G
DEST_DIR="${1:-/Volumes/WinShare/mactime}"
SIZE="${2:-600G}"

# 1) ComputerName
CN=$(scutil --get ComputerName 2>/dev/null || hostname)
# 2) find outgoing interface then mac
IFACE=$(route get default 2>/dev/null | awk '/interface:/{print $2}')
[ -z "$IFACE" ] && IFACE="en0"
MAC_RAW=$(ifconfig "$IFACE" 2>/dev/null | awk '/ether/{print $2}' || true)
if [ -z "$MAC_RAW" ]; then
  # fallback: try networksetup list
  MAC_RAW=$(networksetup -listallhardwareports 2>/dev/null | awk '/Hardware Port: Wi-Fi/{getline; print}' | awk '{print $2}')
fi
MAC=$(echo "$MAC_RAW" | sed 's/://g' | tr '[:upper:]' '[:lower:]')

if [ -z "$MAC" ]; then
  echo "无法检测到 MAC 地址(interface: $IFACE)。请手工指定或检查网络接口。" >&2
  exit 1
fi

FNAME="${CN}_${MAC}.sparsebundle"
TARGET="${DEST_DIR%/}/${FNAME}"

echo "ComputerName: $CN"
echo "Interface: $IFACE"
echo "MAC: $MAC"
echo "Sparsebundle target: $TARGET"
echo "Size: $SIZE"

# sanity
read -p "确认在共享盘已挂载且有写权限?(y/N) " confirm
if [ "${confirm,,}" != "y" ]; then
  echo "取消。请先挂载 SMB 共享并确保可以写入,再运行此脚本。"
  exit 1
fi

# 3) create
echo "开始创建 sparsebundle(这可能需要几分钟)..."
hdiutil create -size "${SIZE}" -type SPARSEBUNDLE \
  -fs "Case-sensitive Journaled HFS+" \
  -volname "TimeMachine" \
  "${TARGET}"

echo "创建完成,尝试挂载..."
hdiutil attach "${TARGET}"

echo "设置 Time Machine 目的地(需要 Full Disk Access)..."
sudo tmutil setdestination "/Volumes/TimeMachine" || {
  echo "tmutil 设置失败,请确认已给 Terminal 完全磁盘访问(Full Disk Access)。"
  exit 1
}

echo "完成。检查 tmutil destinationinfo 输出:"
tmutil destinationinfo

echo "现在可以在 Time Machine 中查看 /Volumes/TimeMachine 作为备份目标,或手动触发备份 (tmutil startbackup --auto)。"

注意

  • 运行脚本前 务必在「系统设置 → 隐私与安全 → 完全磁盘访问」里把 Terminal 加到允许列表(否则 tmutil 可能失败)。(Apple Support)
  • hdiutil create 在共享盘上超时失败,先把目标改为本地目录,创建好后再 cp -Rrsync 到 SMB 共享。(Ask Different)

小技巧与安全建议

  • 加密备份:建议开启 Time Machine 的加密选项(备份镜像可以被加密),以防共享盘被其他人访问时泄露数据。(Apple Support)
  • 命名风格:使用不含空格或奇字符的 ComputerName(例如 MyMacPro)会少出很多麻烦。
    # 配置名字
    sudo scutil --set ComputerName "myMacName"
    sudo scutil --set LocalHostName "myMacName"
    sudo scutil --set HostName "myMacName"
    # 检查
    scutil --get ComputerName
    scutil --get LocalHostName
    scutil --get HostName
    
  • 网络稳定性:网络不稳定会导致远程稀疏包损坏或 create 失败,请尽量在千兆 LAN 环境或稳定 Wi-Fi 下操作。
  • 备份测试:创建完成后立刻手动触发一次 (tmutil startbackup --auto),并尝试还原单个文件,确认备份实际可用。(The Eclectic Light Company)

参考 / 延伸阅读

  • Apple — Backup disks you can use with Time Machine(网络备份与 SMB 相关说明)。(Apple Support)
  • Apple — Back up to a shared folder with Time Machine(如何把文件夹标记为 Time Machine 备份目的地 — 适用于另一台 Mac 做服务器)。(Apple Support)
  • tmutil(Time Machine 命令行工具)手册与用法(setdestination, startbackup 等)。(SS64)
  • 关于 hdiutil create 在某些 SMB 服务上超时的社区讨论(若遇到 create 失败可参考)。(Ask Different)
  • sparsebundle 使用及 compact(回收空间)说明。(Stephen Foskett, Pack Rat)