当我做
sudo umount /media/KINGSTON
我有
umount: /media/KINGSTON: device is busy.
我关闭所有窗口并确保所有 shell 都指向其他目录。如何找到阻止卸载的进程?
答案1
打开终端:
fuser -c /media/KINGSTON
它将输出类似这样的内容:
/media/KINGSTON/: 3106c 11086
这将为您提供使用此卷的进程的 pid。pid 末尾的额外字符将提供一些额外信息。(3106c 中的 c)
c - 进程正在使用该文件作为其当前工作目录
m - 该文件使用 mmap 映射
o - 进程正在将其用作打开文件
r - 该文件是进程的根目录
t - 进程正在将该文件作为文本文件访问
y - 该文件是进程的控制终端
因此,要卸载,只需杀死该 pid,然后重新尝试卸载
sudo kill -9 3106 11086
sudo umount /media/KINGSTON
注意:要查找这些 pid 的确切应用程序名称,您可以使用此命令
cat /proc/<pid>/cmdline
例如 : cat /proc/11086/cmdline
这将输出类似下面的内容。
evince^@/media/KINGSTON/Ubuntu-guide.pdf^@
希望这会有所帮助
答案2
最有用的工具是lsof 。它显示哪些文件正在被哪些进程使用。如果/media/KINGSTON
是挂载点(设备名称也可以),以下命令显示此挂载点上正在使用的所有文件:
lsof /media/KINGSTON
如果您以普通用户身份运行此命令,它将仅显示您自己的进程¹。运行sudo lsof /media/KINGSTON
以查看所有用户的进程。
输出lsof
如下:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh4 31421 gilles cwd DIR 8,1 4096 130498 /var/tmp
zsh4 31421 gilles txt REG 8,1 550804 821292 /bin/zsh4
zsh4 31421 gilles mem REG 8,1 55176 821326 /usr/lib/zsh/4.3.10/zsh/complist.so
zsh4 31421 gilles 12r REG 8,1 175224 822276 /usr/share/zsh/functions/Completion.zwc
列COMMAND
显示程序可执行文件的名称,PID
列显示进程 ID。NAME
列显示文件名;您可能会看到(deleted)
文件是否在打开时被删除(当文件被删除时,它不再有名称,但它仍然存在,直到最后一个使用它的进程关闭该文件)。USER
应该是不言自明的。其他列在这里并不重要,除了也许FD
,它显示了进程如何使用文件:
cwd
:当前工作目录txt
:程序可执行文件²mem
:内存映射文件(这里可以将其视为打开的文件)- 数字:实际打开的文件;后续字母表示打开模式,如
r
读取、w
写入
没有机械的方法来定位打开文件的窗口(这实际上在技术上没有意义:如果一个进程有多个窗口,则文件与某个窗口没有特别的关联),甚至没有任何简单的方法来识别进程的窗口(当然,进程不必有任何窗口)。但通常命令名称和文件名足以找到罪犯并正确关闭文件。
如果您无法关闭文件而只想结束一切,您可以使用kill 31421
(31421
进程 ID 在哪里) 或kill -HUP 31421
(“挂断”) 来终止进程。如果简单的终止不起作用,请以极端方式终止:kill -KILL 31421
。
lsof 有一个 GUI,格索夫,但它还没有完全准备好迎接黄金时段,并且目前还没有为 Ubuntu 打包。
¹
Lsof 可以列出有关其他用户进程的一些信息,但它不会检测挂载点,因此如果您指定挂载点,它将不会列出它们。²
在
可执行格式的讨论中,可执行代码通常被称为文本。
答案3
同时,fuser 命令也得到了很大的改进。你可以用一个命令完成全部工作:
$ sudo fuser -ickv /"mountpoint"
在哪里:
- 参数
k
终止有问题的进程, - 同时
v
提前展示流程及其用户 - 并
i
请您确认。
fuser -ickv -9
如果某个进程抵抗,则使用(或更一般地使用)重试,-SIGNAL
以杀死最顽固的进程。
但你总会找到一些“不朽”的进程……!
在这种情况下,我最近学会了使用
$ sudo umount --lazy --force <mountpoint>
作为最后的资源,到目前为止它每次都对我有用。
答案4
注意!另一个让挂载点忙碌的因素是子挂载,它不是一个进程,因此如果你通过lsof
或搜索,它不会显示出来fuser
。是的,这应该是显而易见的,但是在这个由于 docker 和重新绑定等而产生大量挂载的时代,很容易忽略这一点,例如:
# mount | wc -l
39
# mount |grep usb
/dev/sde1 on /media/usb type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro)
/media/usb/boot/modloop-lts on /.modloop type squashfs (ro,relatime)
/media/usb 由于第二次挂载而无法卸载。(示例取自真实的 Alpine Linux“无盘”系统,我花了大约 10 分钟试图弄清楚为什么无法卸载 /media/usb)