ps -o pid、ppid、stat、exe -e | ps -o pid、ppid、stat、exe -e | grep delete実行可能ファイルパスに「(削除済み)」が追加されました

ps -o pid、ppid、stat、exe -e | ps -o pid、ppid、stat、exe -e | grep delete実行可能ファイルパスに「(削除済み)」が追加されました
ps -o pid,ppid,stat,exe -e | grep deleted

次の出力を生成します。

   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)

これが(deleted)何を意味しているのか、psにパスを追加せずに一覧表示させるにはどうすればよいですか?

答え1

Linuxpsではreadlink("/proc/<pid>/exe")

$ ls -l /proc/self/exe
lrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:35 /proc/self/exe -> /usr/bin/ls

ファイルは魔法のシンボリックリンク特定のプロセス(またはすべてのプロセスがファイルを実行しているわけではないため、親プロセス)の最後のファイル処刑された。ファイルが削除された場合(パッケージの更新後など、新しいバージョンに置き換えられた場合)、返された(deleted)文字列にaが追加されますreadlink()。シンボリックリンクはまだ大丈夫ですすでにフォロー中実際に削除されたファイルに(それで魔法)。

$ cp /bin/sleep .
$ ./sleep 1h &
[1] 17417
$ ls -ld "/proc/$!/exe"
lrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> /home/chazelas/sleep*
$ rm sleep
$ ls -ld "/proc/$!/exe"
lrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> '/home/chazelas/sleep (deleted)'

新しいバージョンsleep:

$ cp /bin/sleep .
$ ps -o exe -p "$!"
EXE
/home/chazelas/sleep (deleted)
$ ls -ld "/proc/$!/exe"
lrwxrwxrwx 1 chazelas chazelas 0 Dec 17 10:38 /proc/17417/exe -> '/home/chazelas/sleep (deleted)'
$ ls -iLd "/proc/$!/exe" sleep
3114951 /proc/17417/exe*  3114969 sleep*

-L ls以下のリンク(で置き換えstat())を使用してlstat()適切なiノード番号を取得してください。

これは2つの異なるファイル(異なるinode番号)であることがわかります。

$!削除された以前のバージョンを引き続き実行している場合、sleepそのファイルには魔法のシンボリックリンク以外のファイルシステムへのパスはありません/proc/$!/exe

/home/chazelas/sleepこれは別の実行可能ファイルなので、削除すると誤ったファイルを参照(deleted)するため、間違っています。ここではexe最後のフィールドなので、出力を次にパイプして削除できます。

sed 's/ (deleted)$//'
$ ps -o pid,ppid,stat,exe
    PID    PPID STAT EXE
  18928   11196 Ss   /usr/bin/zsh
  18943   18928 SN   /home/chazelas/sleep (deleted)
  18967   18928 R+   /usr/bin/ps
$ ps -o pid,ppid,stat,exe | sed 's/ (deleted)$//'
    PID    PPID STAT EXE
  18928   11196 Ss   /usr/bin/zsh
  18943   18928 SN   /home/chazelas/sleep
  18968   18928 R+   /usr/bin/ps
  18969   18928 S+   /usr/bin/sed

/home/chazelas/sleepただし、これはプロセス18943が実行中の実行可能ファイルではないため、嘘かもしれません。sleepプロセスが実行されてから削除されたため、今は見つからない別のコマンドです。


そして、/proc/<pid>/exeファイルを実行したり、/proc/<pid>/fd/<fd>一部のfdでファイルを開くことができる他のプロセスに対応したり、ファイルへのハードリンクがある可能性があります。

答え2

あなたのメモコマンド、使用exe実行可能ファイルパスを印刷するための引数を要求しました。

man procこの領域を詳しく紹介します。

パス名のリンクが解放されると、シンボリックリンクは元のパス名に「(削除済み)」文字列を追加します。

これはオプションではなく(パスの表示を要求するとき)、必ずパスを表示する必要があるため、私が考えることができる唯一の解決策は結果を後処理することです。たとえば、sedを使用すると、次のようになります。

ps -o pid,ppid,stat,exe -e | sed "s/(deleted)//g"

関連情報