diskutil eject:如何从 Mac Terminal 推出驱动器
用 diskutil 从 Terminal 推出任何 Mac 驱动器——包括强制卸载一个无法推出的宗卷,以及用 lsof 找出是什么在占用它。
访达告诉你驱动器正在使用。它不告诉你是什么在使用它,也不告诉你该怎么办。Terminal 两者都能做到。
快速答案: 运行
diskutil eject /Volumes/YourDriveName从 Terminal 推出一个驱动器。如果失败,用sudo lsof /Volumes/YourDriveName查看是什么在阻止推出,用kill <PID>停止那个肇事的进程,然后再推出一次。作为最后手段,diskutil unmountDisk force /dev/diskN会强制卸下驱动器,但仅在没有任何东西正在积极写入时才这样做。
如果你对命令行得心应手,那么在 macOS 上处理顽固的驱动器推出,Terminal 是最强大的方式。而如果你还不太习惯它,这些命令是一个很好的起点。
用 diskutil eject 进行基本推出
从 Mac Terminal 推出外置驱动器最直接的方式:
diskutil eject /Volumes/YourDriveName
将 YourDriveName 替换为驱动器的实际名称——和它在访达中显示的完全一致。如果名称含有空格,就用引号把它括起来:
diskutil eject "/Volumes/My Drive"
这和点按访达中的推出按钮做的是同一件事。如果成功,驱动器会干净地卸载,你就完事了。如果失败,你会看到一条比访达更详细、更有用的错误消息。
你也可以只卸载而不推出(驱动器在磁盘工具中仍可见,但未装载):
diskutil unmount /Volumes/YourDriveName
这个区别对多分区驱动器很重要。unmount 移除一个宗卷。eject 一次性移除物理设备及其所有宗卷。
用 diskutil list 找到驱动器的标识符
在使用更高级的命令之前,你需要驱动器的标识符。列出所有已连接的磁盘:
diskutil list
输出会显示每个磁盘及其分区。你的外置驱动器会是类似 disk4 或 disk5 的形式。内部驱动器通常是 disk0 和 disk1。
要获得仅含外置驱动器、更易读的概览:
diskutil list external
一旦你知道了磁盘标识符,你也可以用 /dev/ 路径而非宗卷名称来推出:
diskutil eject /dev/disk4
当宗卷名称含有不寻常的字符,或宗卷未装载但磁盘仍连接着时,这很有用。
如何一次性推出所有外置驱动器
如果你需要用一条命令推出每一个外置驱动器,有两种途径。
用 diskutil 找出并推出所有外置磁盘:
diskutil list external | grep -o 'disk[0-9]*$' | while read disk; do diskutil eject "/dev/$disk"; done
或者从 Terminal 使用 AppleScript,这模仿了访达所做的事:
osascript -e 'tell application "Finder" to eject (every disk whose ejectable is true)'
AppleScript 这种途径只推出访达认为可推出的磁盘——它会跳过你的启动磁盘和网络宗卷,而这通常正是你想要的。
当 diskutil eject 失败时强制卸载
如果常规推出失败,报出类似“无法卸载磁盘”的错误,就强制它:
diskutil unmount force /Volumes/YourDriveName
或一次性卸载某个特定磁盘上的所有宗卷:
diskutil unmountDisk force /dev/disk4
强制卸载是在告诉 macOS:不管有什么在使用该宗卷,都把它释放掉。它比物理拔掉驱动器更受控——系统仍会刷新缓存并通知进程——但它不会等待进程干净地关闭文件。
在你确知没有重要东西正被写入时使用强制卸载。它相当于从磁盘工具强制推出的命令行版本。在对一个正被积极使用的驱动器使用它之前,请参阅我们的指南:强制推出何时安全、何时有风险。
用 lsof 找出是什么在阻止推出
正是这条命令让 Terminal 在推出问题上无可替代:
lsof /Volumes/YourDriveName
lsof 代表“列出打开的文件”(list open files)。它会显示每一个在该宗卷上打开了文件的进程——进程名称、进程 ID(PID)、运行它的用户,以及打开的是哪个文件。(要了解 lsof 标志和用法的专门讲解,请参阅我们的面向 Mac 用户的 lsof 命令指南。)
要获得完整的结果(包括系统进程),用 sudo 运行它:
sudo lsof /Volumes/YourDriveName
不加 sudo,你只能看到你的用户账户所拥有的进程。像聚焦的 mds 或时间机器的 backupd 这样的系统进程不会出现。加上 sudo,你就能看到一切真正占用着驱动器的东西。
读懂 lsof 的输出
输出看起来大致是这样的:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mds 123 root 12r REG 1,8 4096 789 /Volumes/MyDrive/.Spotlight-V100/...
Finder 456 aaron 15r DIR 1,8 1024 2 /Volumes/MyDrive
Dropbox 789 aaron 8u REG 1,8 8192 345 /Volumes/MyDrive/Projects/.dropbox
最重要的几列:
- COMMAND:进程名称——它告诉你是什么在阻止推出。
- PID:进程 ID——必要时你会用它来终止进程。
- FD:文件描述符和访问模式。
r表示读,w表示写,u表示读/写。如果你看到w或u,说明有东西正在积极向驱动器写入,强制推出有风险。 - NAME:正被访问的具体文件——这往往能揭示该进程为何在那里的确切原因。
常见的肇事者:mds(聚焦索引)、backupd(时间机器)、Dropbox、Google Drive、访达本身。针对性的修复方法,请参阅我们的深入文章:聚焦阻止推出以及 iCloud/Dropbox 妨碍推出。
终止阻止进程
一旦你知道了某个阻止进程的 PID,就温和地终止它:
kill 789
这会发送一个温和的终止信号。进程会得到一个关闭文件并清理的机会。给它几秒钟退出,然后再试着推出。
如果它对温和的终止没有响应:
kill -9 789
这会强制立即终止。进程没有机会清理。把它作为最后手段使用——对系统进程尤其如此。
要用一条命令终止所有使用某个特定宗卷的进程:
sudo lsof -t /Volumes/YourDriveName | xargs kill
-t 标志让 lsof 只输出 PID,而 xargs 把它们喂给 kill。要小心:这会终止每一个使用该驱动器的进程,包括那些可能正处于重要工作中途的进程。
完整的排查工作流程
这里是针对一个无法推出的驱动器的完整流程:
# 第 1 步:尝试常规推出
diskutil eject /Volumes/YourDriveName
# 第 2 步:如果失败,查看是什么在阻止
sudo lsof /Volumes/YourDriveName
# 第 3 步:终止肇事的进程(将 PID 替换为实际数字)
kill 12345
# 第 4 步:再试着推出
diskutil eject /Volumes/YourDriveName
# 第 5 步:如果仍卡住,强制卸载
diskutil unmountDisk force /dev/disk4
大多数问题在第 3 步就解决了。辨认出阻止者,终止它,干净地推出。
有用的诊断变体
专门检查是否是聚焦在占用你的驱动器:
lsof /Volumes/YourDriveName | grep mds
只列出阻止推出的唯一进程名称(无重复行):
lsof /Volumes/YourDriveName | awk '{print $1}' | sort -u
实时观察磁盘 I/O,看看是否有东西在积极写入:
sudo fs_usage -f diskio | grep YourDriveName
这会持续运行,并在每一次磁盘操作发生时显示出来。按 Control-C 停止。当 lsof 显示了一个进程、而你不确定它是在积极写入还是只是持有一个陈旧的句柄时,用它。
当 Terminal 得不偿失时
这些命令很强大,而且一旦你用过几次,它们就会变成第二天性。但从你的工作切换到一个 Terminal 窗口是有实实在在代价的——运行诊断命令、解析技术性输出、判断哪个 PID 可以安全地终止。
Ejecta 会自动完成上述一切。它监测你的驱动器,辨认出每一个阻止进程,并给你一个一键退出每一个进程的按钮。你从 sudo lsof 能得到的同样信息,会以可视化的方式直接呈现在菜单栏里——无需记忆命令,无需解析输出。
只需 9.99 美元,你就能得到一个用单次点按取代这整套多步骤 Terminal 工作流程的工具。如果你每月与这个问题较劲不止一次,那么在头一周里,它就能凭省下的烦恼回本。免费试用 Ejecta 7 天——无需 Terminal。
如果你不想每次都动用终端,Ejecta 会准确告诉你是哪个进程在占用硬盘——只需在菜单栏中点击一下即可退出它。
立即购买 — $9.99