为什么“pgrep firefox”在 Ubuntu 20.04 上不起作用

tre*_*esf 6 grep ubuntu ps firefox pgrep

正如标题所示,在 Ubuntu 20.04 上执行以下命令:

pgrep firefox
Run Code Online (Sandbox Code Playgroud)

...没有返回结果。

同时,执行以下命令:

ps aux |grep firefox
Run Code Online (Sandbox Code Playgroud)

...返回 6 个结果,其中 5 个应匹配pgrep firefox。Ubuntu 上的原始命令有什么问题pgrep

ubuntu     81646  1.9  7.9 3063696 300208 ?      Sl   13:12   0:29 /usr/lib/firefox/firefox -new-window
ubuntu     81891  0.2  3.8 2473448 144796 ?      Sl   13:12   0:03 /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab
ubuntu     82020  0.1  3.7 2438972 141396 ?      Sl   13:12   0:02 /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 897 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab
ubuntu     82051  0.0  2.8 2401248 107520 ?      Sl   13:12   0:01 /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -prefsLen 6935 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab
ubuntu     83658  0.0  2.0 2387704 78496 ?       Sl   13:12   0:00 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 10362 -prefMapSize 222536 -parentBuildID 20200720193547 -appdir /usr/lib/firefox/browser 81646 true tab
ubuntu     90700  0.0  0.0  17664   664 pts/0    S+   13:37   0:00 grep --color=auto firefox
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 18.04 和 macOS 上运行相同的命令效果很好。

Sté*_*las 5

pgrep与进程名称匹配,如pswithout报告-f,而pgrep -f与参数列表匹配,如ps -f或您的非标准报告ps aux

\n

firefox更改其线程的名称以识别每个线程的作用。

\n

尝试(假设默认值$IFS):

\n
ps -L -o comm= -p $(pgrep -wf firefox)\n
Run Code Online (Sandbox Code Playgroud)\n

其中列出了进程中所有线程的名称,参数列表包含firefox,您会看到很多类似的内容:

\n
MainThread\ngmain\ngdbus\nGecko_IOThread\nTimer\nNetlink Monitor\nSocket Thread\nPermission\nJS Watchdog\nJS Helper\n[...]\n
Run Code Online (Sandbox Code Playgroud)\n

因此,对于firefox,您可能希望在参数列表(他们或其父级执行的最后一个命令的参数列表,如果有的话)上与(如果您想列出所有线程则pgrep -f firefox添加)进行匹配,而不是进程/线程名称。-w或者pgrep -f '^[^ ]*firefox'仅匹配该 arg 列表的第一个单词(pgrep在匹配之前将参数与空格连接起来,如 in ps -f)。

\n

在任何情况下,任何进程都可以将其进程名称或参数列表设置或更改为它们想要的任何内容\xc2\xb9,因此以这种方式查找进程绝非万无一失。

\n

如果您想匹配当前正在运行/usr/lib/firefox/firefox可执行文件的进程,在 Linux 上并使用zsh

\n
print -rC1 /proc/<1->/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)\n
Run Code Online (Sandbox Code Playgroud)\n

或者对于线程:

\n
print -rC1 /proc/<1->/task/*/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,如果您没有超级用户权限,您可能无法获取未以您身份运行的进程的信息)。

\n

或者可能稍微更便携lsof

\n
lsof -Fd /usr/lib/firefox/firefox | sed '/^p/h;/^ftxt/!d;g;s/^p//'\n
Run Code Online (Sandbox Code Playgroud)\n

或者对于线程:

\n
lsof -K -FKd /usr/lib/firefox/firefox | sed '/^K/h;/^ftxt/!d;g;s/^K//'\n
Run Code Online (Sandbox Code Playgroud)\n
\n

\xc2\xb9 但请注意,进程名称长度通常是有限的(Linux 上为 15 个字节),并且根据操作系统和操作系统版本,系统无法轻松提供所有 arg 列表以供检查。

\n


tre*_*esf 2

pgrep firefox为什么在 Ubuntu 20.04 上不起作用

因为这是一个错误: https://bugzilla.mozilla.org/show_bug.cgi ?id= 1649010。

解决方法是:

pgrep "firefox|MainThread"
Run Code Online (Sandbox Code Playgroud)

为什么这有效?

  • 当 Ubuntu 上的 Firefox 79 运行时,它会写入一个值MainThreadto /proc/<pid>/comm(感谢 @steeldriver 在上面的评论/问题部分指出了这一点)
  • pgrep然后使用来自 的值/proc/<pid>/comm来查找与命令匹配的内容
  • 管道分隔符|允许pgrep匹配多个值。建议保留firefoxAND MainThread,以便此命令在旧版本(例如 Ubuntu 18.04 + Firefox 78)上仍然可以成功,在旧版本上pgrep firefox仍然可以正常工作。

为什么这可能不准确?

  • 警告:任何进程名称MainThread不是 firefox 的进程也将报告为使用此技术正在运行。谨慎使用。
  • 警告:多个进程可能处于活动状态。请参阅此答案以找出原因:https://unix.stackexchange.com/a/607242/190347
  • 注意pgrep -x "firefox|MainThread":建议精确匹配

我们还有什么其他选择?

  • 正如@steeldriver 指出的那样,人们可以推断这pgrep -f firefox是一个合适的替代品。它遭受类似的命运,因为它可能匹配其中MainThread包含的命令(例如目录名、文件名等)。firefox出于这个原因,我发现它比字符串更有可能匹配恶意进程,因此更有可能抛出误报MainThread。这是基于经验的预感,没有书面证据,但在 GitHub 上快速搜索表明这MainThread不是一个常见的项目名称(58 个结果,而不是firefox匹配 21,000 个存储库
  • 或者,使用命令/技术的组合来过滤误报可能优于所有其他方法(例如查找两个命令的结果的并集)
  • 问。在直接询问 Mozilla 为什么会发生这种情况后,我们了解到了该错误:https://bugzilla.mozilla.org/show_bug.cgi ?id=1662232