如何从进程名称获取进程ID?

dhr*_*hrm 6 macos bash awk grep

我正在尝试创建一个shell脚本,在我的Mac上获取Skype应用程序的进程ID.

ps -clx | grep'Skype'| awk'{print $ 2}'| 头-1

以上工作正常,但有两个问题:

1) 如果grep命令名称只包含"Skype",则会获得所有进程.如果进程名称恰好是Skype,我怎样才能确保它只获得结果?

2) 我想从中创建一个shell脚本,可以从终端使用,但进程名称应该是此脚本的参数:

#!/bin/sh

ps -clx | grep '$1' | awk '{print $2}' | head -1
Run Code Online (Sandbox Code Playgroud)

这不会返回任何东西.我认为这是因为awk中的$ 2也被视为一个参数.我怎么解决这个问题?

Dav*_* W. 14

您的ps -cl1输出如下所示:

  UID   PID  PPID        F CPU PRI NI       SZ    RSS WCHAN     S             ADDR TTY           TIME CMD
  501   185   172      104   0  31  0  2453272   1728 -      S    ffffff80145c5ec0 ??         0:00.00 httpd
  501   303     1 80004004   0  31  0  2456440   1656 -      Ss   ffffff8015131300 ??         0:11.78 launchd
  501   307   303     4004   0  33  0  2453456   7640 -      S    ffffff8015130a80 ??         0:46.17 distnoted
  501   323   303 40004004   0  33  0  2480640   9156 -      S    ffffff80145c4dc0 ??         0:03.29 UserEventAgent
Run Code Online (Sandbox Code Playgroud)

因此,每行中的最后一个条目是您的命令.这意味着您可以使用正则表达式的全部功能来帮助您.

$正则表达式表示字符串的结尾,因此,你可以使用$指定不仅输出必须Skype在它,它必须结束Skype.这意味着如果你有一个被调用的命令Skype Controller,你就不会把它拉起来:

ps -clx | grep 'Skype$' | awk '{print $2}' | head -1
Run Code Online (Sandbox Code Playgroud)

您还可以使用ps -o格式简化事项,只需提取所需的列:

ps -eo pid,comm | grep 'Skype$' | awk '{print $1}' | head -1
Run Code Online (Sandbox Code Playgroud)

而且,您可以head通过简单地使用awk为您选择行的能力来消除.在awk,NR是你的记录号码.因此你可以这样做:

ps -eo pid,comm | grep 'Skype$' | awk 'NR == 1 {print $1}'
Run Code Online (Sandbox Code Playgroud)

哎呀,既然我想到了,我们也可以消除它grep:

ps -eo pid,comm | awk '/Skype$/  {print $1; exit}'
Run Code Online (Sandbox Code Playgroud)

这是使用awk使用正则表达式的能力.如果该行包含正则表达式'Skype $',它将打印第一列,然后退出

唯一的问题是如果你有一个命令Foo Skype,这也会捡起它.要消除这种情况,你必须做更多花哨的步法:

ps -eo pid,comm | while read pid command
do
    if [[ "$command" = "Skype" ]]
    then
        echo $pid
        break
    fi
done
Run Code Online (Sandbox Code Playgroud)

while read是读书的两个变量.诀窍是read使用空格来划分它读入的变量.但是,由于只有两个变量,最后一个变量将包含整个行的其余部分.因此,如果该命令是Skype控制器,$command即使其中有空格,也将放入整个命令.

现在,我们不必使用正则表达式.我们可以将命令与相等进行比较.

输入时间较长,但实际上您使用的命令更少,管道更少.记住awk循环遍历每一行.你在这里所做的只是让它更明确.最后,这实际上比你原来的效率要高得多.