正如标题所示,在 Ubuntu 20.04 上执行以下命令:
pgrep firefox
...没有返回结果。
同时,执行以下命令:
ps aux |grep firefox
...返回 6 个结果,其中 5 个应匹配pgrep firefox
。pgrep
Ubuntu 上的原始命令有什么问题?
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
在 Ubuntu 18.04 和 macOS 上运行相同的命令效果很好。
答案1
pgrep
与进程名称匹配,如ps
without报告-f
,而pgrep -f
与参数列表匹配,如ps -f
或您的非标准ps aux
.
firefox
更改其线程的名称以识别每个线程的作用。
尝试(假设默认值$IFS
):
ps -L -o comm= -p $(pgrep -wf firefox)
其中列出了名字包含参数列表的进程中的所有线程firefox
,您将看到很多类似的内容:
MainThread
gmain
gdbus
Gecko_IOThread
Timer
Netlink Monitor
Socket Thread
Permission
JS Watchdog
JS Helper
[...]
因此,对于firefox
,您可能希望在参数列表(他们或其父级执行的最后一个命令的参数列表,如果有的话)上与pgrep -f firefox
(-w
如果您想列出所有线程则添加)进行匹配,而不是进程/线程名称。或者pgrep -f '^[^ ]*firefox'
仅匹配该 arg 列表的第一个单词(pgrep
在匹配之前将参数与空格连接起来,如 in ps -f
)。
在任何情况下,任何进程都可以将其进程名称或参数列表设置或更改为它们想要的任何内容,因此以这种方式查找进程绝非万无一失。
如果您想匹配当前正在运行/usr/lib/firefox/firefox
可执行文件的进程,在 Linux 上并使用zsh
:
print -rC1 /proc/<1->/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)
或者对于线程:
print -rC1 /proc/<1->/task/*/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)
(请注意,如果您没有超级用户权限,您可能无法获取未以您身份运行的进程的信息)。
或者可能稍微更便携lsof
:
lsof -Fd /usr/lib/firefox/firefox | sed '/^p/h;/^ftxt/!d;g;s/^p//'
或者对于线程:
lsof -K -FKd /usr/lib/firefox/firefox | sed '/^K/h;/^ftxt/!d;g;s/^K//'
1 尽管请注意,进程名称长度通常是有限的(Linux 上为 15 个字节),并且根据操作系统和操作系统版本,并非所有 arg 列表都可以轻松地由系统提供以供检查。
答案2
pgrep firefox
为什么在 Ubuntu 20.04 上不起作用
因为这是一个错误: https://bugzilla.mozilla.org/show_bug.cgi?id=1649010。
解决方法是:
pgrep "firefox|MainThread"
为什么这有效?
- 当 Ubuntu 上的 Firefox 79 运行时,它会写入一个值
MainThread
to/proc/<pid>/comm
(感谢 @steeldriver 在上面的评论/问题部分指出了这一点) pgrep
然后使用来自 的值/proc/<pid>/comm
来查找与命令匹配的内容- 管道
|
分隔符允许pgrep
匹配多个值。建议保留firefox
AND ,以便此命令在旧版本(例如 Ubuntu 18.04 + Firefox 78)上仍然可以成功,在旧版本上仍然可以正常工作。MainThread
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