ps -o pid,ppid,stat,exe -e | ps -o pid,ppid,stat,exe -e | grep删除已将“(已删除)”附加到可执行路径

Dav*_*ane 9 linux ps proc

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 列出路径而不附加它?

Sté*_*las 9

在 Linux 上,ps通过执行readlink("/proc/<pid>/exe").

\n
$ 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()

\n
$ 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

\n
$ 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

我们看到这是两个不同的文件(不同的索引节点号)。

\n

$!仍在运行旧的已删除版本sleep,该文件在文件系统上除了神奇的符号链接 \xc2\xb9 之外没有任何路径/proc/$!/exe

\n

/home/chazelas/sleep现在是一个不同的可执行文件,因此删除它 (deleted)会是错误的,因为它会引用错误的文件。在这里,由于exe是最后一个字段,您可以通过将输出管道传输到以下位置来删除它:

\n
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命令,现在无处可寻,因为自从该进程执行它以来它已被删除。

\n
\n

\xc2\xb9 并对应/proc/<pid>/exe于可能执行该文件的其他进程或/proc/<pid>/fd/<fd>在某些 fd 上打开该文件的进程,或者可能存在指向该文件的某些硬链接。

\n