我如何找出哪个进程阻止了卸载?

我如何找出哪个进程阻止了卸载?

当我做

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 安装 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)

相关内容