如何防止“ps”报告其自身的进程?

如何防止“ps”报告其自身的进程?
$ 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)被报告?

(我开始尝试提出一个可以匹配文字但不匹配自身的正则表达式,但这似乎不是正确的方法......)

答案1

我的答案是针对在列表中搜索“foobar”的典型答案的变体ps。我认为的参数比的参数"-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
}

答案2

+1 感谢@jamzed 的简洁回答,但是 OP 可能需要一些解释:

ps | grep "[d]jango"

使用该正则表达式,您将启动一个进程,该进程的 ps 字符串将不匹配自身,因为正则表达式匹配"django"而不是"[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.

答案3

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]

答案4

哦,等等,这个有效:

ps | grep django | grep -v grep

相关内容