如何在Mac OS X中通过进程名获取进程的PID?

70
我正在编写一个脚本来监视任何给定进程的CPU和MEM。为此,我需要将要监视的进程名称作为命令行参数发送。例如。
./monitorscript <pname>

我需要在脚本中获取进程的pid,以便可以在其中使用ps -p <pid>

如何根据进程名称获取进程的pid?

我知道可能存在多个相同名称的进程。我只想从该列表中获取第一个进程。


6
如果pgrep可用,你只需输入pgrep 进程名称这篇文章讨论了在OSX上可用的pgrep - another.anon.coward
9个回答

104

上面的答案基本正确,只需要针对Mac OSX中的不同参数进行一些微调。

ps -A | grep [f]irefox | awk '{print $1}'

2
如果应用程序正在运行,则返回正确的PID,但如果该特定应用程序未运行,则返回一个不正确的数字。我使用的是OS X 10.9操作系统。 - modus
8
如果应用程序没有运行,它可能会返回grep进程的PID。请看我的答案。 - stepmuel
刚刚测试了一下pidof adb,没有显示任何内容。不过对于某些进程是有效的。 - Kristof
1
@mohacs @stepmuel 要修复这个问题,请执行 ps -A | grep -m1 [f]irefox | awk '{print $1}' - Motsel
2
许多进程都与带有基本进程名称作为前缀的辅助进程相关联,例如process-helper、processd、processScriptRunner等。-m1仅选择pid的第一个匹配项,这可能不是您想要的。ps -A输出包括pid、tty、time和cmd列。cmd包括执行进程的完整命令。使用-c标志将cmd列输出减少到仅包括进程名称。在grep搜索字符串中添加行尾锚点以消除输出中的辅助进程。ps -Ac | grep -m1 ‘process$’ | awk '{print $1}' - pkfm
如果应用程序未运行,则可能返回grep进程的PID。没错!我的意思是,在不运行Firefox的情况下在终端中尝试运行这个命令会失败,而且没有任何前缀之类的东西。这是错误的! - DoctorPangloss

66

你可以像下面的例子一样使用pgrep命令

$ pgrep Keychain\ Access
44186

这非常有用!谢谢! - Tim Penner
工作得很好。还有一个有用的提示是,如果你想要杀死进程,可以考虑使用 pgrep 的兄弟命令 pkill。更多信息请参阅 man pgrep - inostia

65

您可以使用Homebrew安装pidof

brew install pidof
pidof <process_name>

15
最简朴实用。 - Nate
1
这里有一个很好的pidof来源 https://www.cyberciti.biz/faq/linux-pidof-command-examples-find-pid-of-program/ - Leo Caseiro

7

这个解决方案更加严格地匹配进程名称:

ps -Ac -o pid,comm | awk '/^ *[0-9]+ Dropbox$/ {print $1}'

这个解决方案具有以下优点:
  • 它忽略了类似 tail -f ~/Dropbox 的命令行参数
  • 它忽略了目录内的进程,例如 ~/Dropbox/foo.sh
  • 它忽略了名称类似于 ~/DropboxUID.sh 的进程

6
这是我能找到的最短命令,可以完成此任务:
ps -ax | awk '/[t]he_app_name/{print $1}'

在第一个字母周围加上括号可以阻止awk找到awk进程本身。



2
尝试这个:

试试这个:

echo "$(ps -ceo pid=,comm= | awk '/firefox/ { print $1; exit }')"
< p > ps 命令会产生这样的输出,第一列是 PID,第二列是可执行文件名(仅限于名称):

bookworm% ps -ceo pid=,comm=
    1 launchd
   10 kextd
   11 UserEventAgent
   12 mDNSResponder
   13 opendirectoryd
   14 notifyd
   15 configd

...which awk处理,打印第一列(pid),并在第一个匹配后退出。


1

你可以试试这个

pid=$(ps -o pid=,comm= | grep -m1 $procname | cut -d' ' -f1)

轻微的改进:去除进程路径,以避免任何意外匹配,并匹配所有进程 - 使用 pid = $(ps -ceo ...) - Nicholas Riley
当我在终端中输入 echo "$(ps -ceo pid=,comm= | grep -m1 firefox | cut -d' ' -f1)" 时,我没有得到任何响应。我做错了什么吗? - Pradep
grep 的结果是 firefox-bin 777,有 3 个空格,请使用 cut -d' ' -f3 - jackjr300
pid列右对齐,我没有测试过。我想我会在另一个答案中放置它 :-) - Nicholas Riley
对于我来说,pid=$(ps aux -ceo pid=,comm= | grep -m1 "prl_naptd" | cut -w -f2) 在 macOS 13 上有效。 - Bineesh

0

ps -o ppid=$(ps -ax | grep nameOfProcess | awk '{print $1}')

输出变化的进程PID,然后是父进程PID。您可以杀死父进程,或者使用该parentPID在以下命令中获取父进程的名称:

ps -p parentPID -o comm=

对我来说,父进程是'login' :\


-2
为什么不运行TOP命令并使用选项按照除了PID之外的其他指标进行排序呢?比如,根据CPU/MEM中最高使用的PID进行排序?
top -o cpu <--- 按照CPU使用率对所有进程进行排序

1
这不是问题所在。 - bergercookie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接