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 上运行相同的命令效果很好。
pgrep
与进程名称匹配,如ps
without报告-f
,而pgrep -f
与参数列表匹配,如ps -f
或您的非标准报告ps aux
。
firefox
更改其线程的名称以识别每个线程的作用。
尝试(假设默认值$IFS
):
ps -L -o comm= -p $(pgrep -wf firefox)\n
Run Code Online (Sandbox Code Playgroud)\n其中列出了进程中所有线程的名称,参数列表包含firefox
,您会看到很多类似的内容:
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
)。
在任何情况下,任何进程都可以将其进程名称或参数列表设置或更改为它们想要的任何内容\xc2\xb9,因此以这种方式查找进程绝非万无一失。
\n如果您想匹配当前正在运行/usr/lib/firefox/firefox
可执行文件的进程,在 Linux 上并使用zsh
:
print -rC1 /proc/<1->/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)\n
Run Code Online (Sandbox Code Playgroud)\n或者对于线程:
\nprint -rC1 /proc/<1->/task/*/exe(Ne['[[ $REPLY -ef /usr/lib/firefox/firefox ]]']:h:t)\n
Run Code Online (Sandbox Code Playgroud)\n(请注意,如果您没有超级用户权限,您可能无法获取未以您身份运行的进程的信息)。
\n或者可能稍微更便携lsof
:
lsof -Fd /usr/lib/firefox/firefox | sed '/^p/h;/^ftxt/!d;g;s/^p//'\n
Run Code Online (Sandbox Code Playgroud)\n或者对于线程:
\nlsof -K -FKd /usr/lib/firefox/firefox | sed '/^K/h;/^ftxt/!d;g;s/^K//'\n
Run Code Online (Sandbox Code Playgroud)\n\xc2\xb9 但请注意,进程名称长度通常是有限的(Linux 上为 15 个字节),并且根据操作系统和操作系统版本,系统无法轻松提供所有 arg 列表以供检查。
\n
pgrep firefox
为什么在 Ubuntu 20.04 上不起作用
因为这是一个错误: https://bugzilla.mozilla.org/show_bug.cgi ?id= 1649010。
解决方法是:
pgrep "firefox|MainThread"
Run Code Online (Sandbox Code Playgroud)
为什么这有效?
MainThread
to /proc/<pid>/comm
(感谢 @steeldriver 在上面的评论/问题部分指出了这一点)pgrep
然后使用来自 的值/proc/<pid>/comm
来查找与命令匹配的内容|
允许pgrep
匹配多个值。建议保留firefox
AND MainThread
,以便此命令在旧版本(例如 Ubuntu 18.04 + Firefox 78)上仍然可以成功,在旧版本上pgrep firefox
仍然可以正常工作。为什么这可能不准确?
MainThread
不是 firefox 的进程也将报告为使用此技术正在运行。谨慎使用。pgrep -x "firefox|MainThread"
:建议精确匹配我们还有什么其他选择?
pgrep -f firefox
是一个合适的替代品。它遭受类似的命运,因为它可能匹配其中MainThread
包含的命令(例如目录名、文件名等)。firefox
出于这个原因,我发现它比字符串更有可能匹配恶意进程,因此更有可能抛出误报MainThread
。这是基于经验的预感,没有书面证据,但在 GitHub 上快速搜索表明这MainThread
不是一个常见的项目名称(58 个结果,而不是firefox
匹配 21,000 个存储库)