如何防止“ ps”报告自己的过程?


52
$ ps | grep django
28006 ttys004    0:01.12 /usr/bin/python bin/django celeryd --beat
51393 ttys005    0:01.45 /usr/bin/python bin/django celeryd -l INFO
51472 ttys005    0:01.29 /usr/bin/python bin/django celeryd -l INFO
51510 ttys005    0:01.89 /usr/bin/python bin/django celeryd -l INFO
51801 ttys005    0:01.83 /usr/bin/python bin/django celeryd -l INFO
53470 ttys005    0:03.97 /usr/bin/python bin/django celeryd -l INFO
53780 ttys005    0:00.00 grep django

有什么方法可以防止报告上一个进程(即与我的ps命令同时启动的grep)?

(我开始尝试提出一个正则表达式,该正则表达式将与字面值匹配,但与自身不匹配,但这似乎是不正确的方法……)

Answers:


14

我的答案是在ps列表中搜索“ foobar”的典型答案的变体。我认为,的论据"-A" "ps"比更具说服力"aux",但是此更改与答案无关。典型的答案如下所示:

$ ps -A -ww | grep [f]oobar

相反,我使用这种模式:

$ ps -A -ww | grep [^]]foobar

主要优点是基于此模式编写脚本更加容易,因为您只需将静态字符串[^]]与所需的任何模式连接即可。您无需剥离字符串的第一个字母,然后将其插入方括号之间,然后再次将其连接在一起。使用shell脚本编写脚本时,只需将其粘贴[^]]在您正在寻找的模式前面就容易了。Bash中的字符串切片是一个丑陋的事情,因此我的变体避免了这种情况。此变化表示在不匹配前导右方括号]的情况下显示模式匹配的线。由于排除方括号的搜索模式实际上会将方括号添加到模式中,因此它永远不会匹配自己。

因此,您可以编写一个可移植的psgrep命令,如下所示。在这里,我考虑了Linux,OS X BSD和其他操作系统之间的差异。这会添加来自的列标题ps,从而提供更多自定义ps更好地适合我的需求的格式,并显示列出更多,更宽的进程,因此不会遗漏任何命令行参数。好吧,大多数都不会错过。Java是Java,它通常以最坏的方式处理事情,因此您某些Java服务将超出进程表将跟踪的最大允许参数长度。我相信这是1024个字符。允许启动进程的命令长度很长,但是内核进程表不会费心跟踪任何长度超过1K的内容。一旦启动命令,就不需要使用命令名和参数列表,因此存储在进程表中的内容仅供参考。

psgrep ()
{
    pattern=[^]]${1};
    case "$(uname -s)" in
        Darwin)
            ps -A -ww -o pid,ppid,nice,pri,pcpu,pmem,etime,user,wchan,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        Linux)
            ps -A -ww -o pid,ppid,tid,nice,pri,pcpu,pmem,etime,user,wchan:20,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        *)  # other UNIX flavors get a minimalist version.
            ps -A -ww | grep -i -e ${pattern}
        ;;
    esac
}

缺点是,它实际上比原始模式多匹配一个字符(在前面)。例如,这将永远与PID不匹配。与一起使用时可能会产生误导grep --colour
Tonin

67

+1为@jamzed简洁答案,但是OP可能需要一些解释:

ps | grep "[d]jango"

使用该正则表达式,您将启动一个其ps字符串自身不匹配的进程,因为regexp与"django"not 匹配"[d]jango"。这样,您将排除具有字符串“ [d] jango”的进程,在本例中为grep;可以将同样的方法应用于pgrep,egrep,awk,sed等...您用来定义正则表达式的任何命令。

从man 7 regex

   A bracket expression is a list of characters enclosed in "[]".  It nor‐
   mally matches any single character from the list (but see  below).   If
   the  list  begins  with  '^',  it matches any single character (but see
   below) not from the rest of the list.  If two characters  in  the  list
   are  separated  by '-', this is shorthand for the full range of charac‐
   ters between those two (inclusive) in the collating sequence, for exam‐
   ple,  "[0-9]" in ASCII matches any decimal digit.  It is illegal(!) for
   two ranges to share an endpoint, for example, "a-c-e".  Ranges are very
   collating-sequence-dependent,  and portable programs should avoid rely‐
   ing on them.

2
凉。我实际上对正则表达式非常满意,但无法立即想到防止正则表达式匹配的方法。将一个字母括在方括号中是很有意义的。(包括[^!]之类的内容也可以使用...)
史蒂夫·贝内特

1
很好而且很狡猾。
灰烬

对于特定于'ps'的情况,我在要搜索的进程名称的开头使用'[]'。然后,我不需要专门为正则表达式解析进程名称,但是它仍然匹配。
Neromancer 2014年

@hmontoliu例如,它不起作用ps aux | grep [s]cript1。您能帮忙评论一下该解决方案吗?
SOUser

@hmontoliu我的错。似乎由于先前的搜索而显示了该行...
SOUser

30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


如果需要grep一个字符,请添加空间:ps aux| grep "[Z] "
2015年

@jamzed不适用于例如:ps aux | grep [s]cript1ps aux | grep [s]cript2。grep行仍然显示。您能帮忙评论一下该解决方案吗?
SOUser

@jamzed我的错。似乎由于先前的搜索而显示了该行...
SOUser

18

使用pgrep代替: pgrep -lf django


像往常一样,我忘记提及平台(在这种情况下为OS X)。大概pgrep可以在各种Linux上运行。
史蒂夫·本内特

我不同意,@ ramruma。我之所以来到这个话题正是因为pgrep给了我这个问题。但是我必须说我正在CygWin中对其进行测试(ps无法显示进程的完整命令行)。
Sopalajo de Arrierez 2014年

该手册指出“正在运行的pgrep或pkill进程将永远不会将自己报告为匹配项。”实际上,我还没有看到它这样做。
deltab,2016年

我一直在处理一个我认为pgrep与自己匹配的问题。原来,它与bash我从中运行脚本文件的名称匹配。添加-xfixed,然后在命令名称上进行完全匹配。
andynormancx


8

ps -d | grep django

来自人ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

仍然在我的
Kevin

是的,这对我的作品在OS X上
史蒂夫·贝内特

在Linux上效果不佳。
Acumenus

更普遍地讲,的选项ps众所周知是不可移植的,因此,如果没有有关该平台用于哪个平台的信息,此答案就不会很有帮助。此外,当您不确定要查找的进程不是进程领导者时,这显然是不够的(即,如果目标是守护程序,则可能会有所帮助,但通常情况下并非如此)。
Tripleee'4

有趣的是,在Mac上,这似乎显示grep进程并过滤掉所有其他内容。
Christopher Hunter,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.