ps -o pid,ppid,stat,exe -e | grep deleted
Run Code Online (Sandbox Code Playgroud)
生成如下输出:
1777 1346 Sl /usr/bin/python3.10 (deleted)
1778 1346 Sl /usr/bin/python3.10 (deleted)
1825 1327 Ss /usr/lib/bluetooth/obexd (deleted)
2007 1 Sl /usr/bin/python3.10 (deleted)
2101 1346 S /usr/bin/python3.10 (deleted)
2199 1 Sl /usr/bin/python3.10 (deleted)
371565 371305 SLl /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess (deleted)
371566 371305 SLl /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess (deleted)
376426 371305 SLl /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess (deleted)
380141 371305 SLl /usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess (deleted)
Run Code Online (Sandbox Code Playgroud)
这是什么(deleted)
意思以及如何让 ps 列出路径而不附加它?
在 Linux 上,ps
通过执行readlink("/proc/<pid>/exe")
.
$ ls -l /proc/self/exe\nlrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:35 /proc/self/exe -> /usr/bin/ls\n
Run Code Online (Sandbox Code Playgroud)\n该文件是给定进程(或其任何祖先,因为并非所有进程都执行文件)最后执行的文件的神奇符号链接。如果文件已被删除(并且可能被新版本替换,例如软件包更新后),则 a会附加到 . 返回的字符串中。该符号链接仍然可以跟踪到实际删除的文件(这样它就很神奇)。 (deleted)
readlink()
$ cp /bin/sleep .\n$ ./sleep 1h &\n[1] 17417\n$ ls -ld "/proc/$!/exe"\nlrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> /home/chazelas/sleep*\n$ rm sleep\n$ ls -ld "/proc/$!/exe"\nlrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> '/home/chazelas/sleep (deleted)'\n
Run Code Online (Sandbox Code Playgroud)\n新版本sleep
:
$ cp /bin/sleep .\n$ ps -o exe -p "$!"\nEXE\n/home/chazelas/sleep (deleted)\n$ ls -ld "/proc/$!/exe"\nlrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> '/home/chazelas/sleep (deleted)'\n$ ls -iLd "/proc/$!/exe" sleep\n3114951 /proc/17417/exe* 3114969 sleep*\n
Run Code Online (Sandbox Code Playgroud)\n用-L
ls
下面的链接(用stat()
代替lstat()
)就可以得到对应的i
节点号。
我们看到这是两个不同的文件(不同的索引节点号)。
\n$!
仍在运行旧的已删除版本sleep
,该文件在文件系统上除了神奇的符号链接 \xc2\xb9 之外没有任何路径/proc/$!/exe
。
/home/chazelas/sleep
现在是一个不同的可执行文件,因此删除它 (deleted)
会是错误的,因为它会引用错误的文件。在这里,由于exe
是最后一个字段,您可以通过将输出管道传输到以下位置来删除它:
sed 's/ (deleted)$//'\n
Run Code Online (Sandbox Code Playgroud)\n$ ps -o pid,ppid,stat,exe\n PID PPID STAT EXE\n 18928 11196 Ss /usr/bin/zsh\n 18943 18928 SN /home/chazelas/sleep (deleted)\n 18967 18928 R+ /usr/bin/ps\n$ ps -o pid,ppid,stat,exe | sed 's/ (deleted)$//'\n PID PPID STAT EXE\n 18928 11196 Ss /usr/bin/zsh\n 18943 18928 SN /home/chazelas/sleep\n 18968 18928 R+ /usr/bin/ps\n 18969 18928 S+ /usr/bin/sed\n
Run Code Online (Sandbox Code Playgroud)\n但同样,这将是一个谎言,因为/home/chazelas/sleep
它不是进程 18943 正在运行的可执行文件,它是另一个sleep
命令,现在无处可寻,因为自从该进程执行它以来它已被删除。
\xc2\xb9 并对应/proc/<pid>/exe
于可能执行该文件的其他进程或/proc/<pid>/fd/<fd>
在某些 fd 上打开该文件的进程,或者可能存在指向该文件的某些硬链接。