如何防止“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)被报告?

(我开始试图提出一个符合字面意思的正则expression式,但是它本身并不匹配,但是看起来这不是正确的方法…)

我的答案是在ps列表中search“foobar”的典型答案的变体。 我相信"-A" "ps"这个说法比"aux"更具可移植性,但是这个改变与答案无关。 典型的答案是这样的:

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

相反,我使用这种模式:

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

主要的优点是,基于这种模式编写脚本比较容易,因为您只需将静态string[^]]与您正在寻找的任何模式连接起来。 您不需要去掉string的第一个字母,然后将其插入方括号之间,然后再将它们连接在一起。 在shell中编写脚本时,将[^]]简单地粘贴到您寻找的模式的前面会更容易。 在Bash切片的string是一个丑陋的东西,所以我的变化避免了这一点。 这种变化说明模式匹配没有领先的右方括号]。 由于排除方括号的search模式实际上将方括号添加到模式中,所以它将永远不会匹配自身。

所以你可以写一个便携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 } 

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

 ps | grep "[d]jango" 

使用该正则expression式,你正在启动一个进程,其psstring不会匹配自己,因为正则expression式匹配"django"而不是"[d]jango" 。 这样,你将排除具有string“[d] jango”的进程,在这种情况下是grep; 同样可以应用到pgrep,egrep,awk,sed等等,无论你用什么命令来定义正则expression式。

从男人7正则expression式

  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, "ace". Ranges are very collating-sequence-dependent, and portable programs should avoid rely‐ ing on them. 

ps | grep [d]jango

ps | grep d[j]ango

ps | grep djang[o]

改用pgrep: pgrep -lf django

哦,等等,这个作品:

 ps | grep django | grep -v grep 

ps -d | grep django

从男人ps:

  -d Lists information about all processes except session leaders.