当我搜索某个不存在的进程时,例如

$ ps aux | grep fnord                          
wayne    15745  0.0  0.0  13580   928 pts/6    S+   03:58   0:00 grep fnord


很显然,我并不关心grep-与搜索ps进程一样有意义!

如何防止grep在结果中显示?

评论

如果仅需要进程的PID,则可以用pgrep(或pgrep -f)替换ps aux | grep。

关于Serverfault和超级用户的相同问题。

这是合法的输出吗?似乎没有名为fnord的程序正在运行...

@acolyte,就是这样-但是因为它将输出管道输送到grep中,所以grep正在运行(我希望等待ps aux的输出)。所以问题是如何防止grep fnord显示为正在运行的进程,因为显然我对此不感兴趣。

@acolyte,您看不到“ fnord”行并不奇怪。您不应该能够看到它。如果您有2到3分钟的空闲时间,请进行搜索。

#1 楼

原来,在钥匙串中找到了解决方案。字符“ f”后跟“ nord”。”

,但是由于您将方括号放在模式“ f”中,因此其后是“]”,因此grep将不会显示在结果列表中。 Neato!

评论


@acolyte:ps的输出将包含以grep [f] nord结尾的行。但是,该行不会通过grep过滤器加入,因为字符串[f] nord与正则表达式[f] nord不匹配。

– LarsH
13年4月30日在17:58

@LarsH有趣,谢谢!我会建议ps aux | grep fnord | grep -v grep ...似乎已经有人建议了...大声笑

– acolyte
13年4月30日在18:16



@progo是的,您确实需要引用[甚至以bash引用。在当前目录中使用名为fnord的文件尝试。

–吉尔斯'所以-不再是邪恶的'
13年5月1日在22:18

掌握ps的输出可能是一个古老的技巧,但并不可靠。如果可用,请使用pgrep。

–吉尔斯'所以-不再是邪恶的'
13年5月1日在22:19

@naxa假设您有一个名为fnord的程序和一个名为safnorde的程序。或者有一个名为bfnord的用户,您最终将杀死他的所有进程。等等。

–吉尔斯'所以-不再是邪恶的'
13年11月24日在22:37

#2 楼

我使用的另一个选项(特别是仅用于查看进程是否正在运行)是pgrep
命令。这将搜索匹配的过程,但不会列出搜索的grep行。我喜欢它,因为它是一种快速的搜索方式,无需重新定义或转义任何内容。

pgrep fnord


评论


他们将希望-f选项更像ps | grep。

–jordanm
13年4月30日在14:16

@jordanm实际上,pgrep -f看起来更像ps -f | grep。

– michelpm
13年4月30日在18:09



还有-l参数,以使其显示要匹配的命令。

–干粉
13年5月1日下午3:34

ps | grep'[f] nord'是聪明而古老的,但是pgrep是正确的。

– kojiro
13年5月1日在11:33

如果`pgrep缺少选项(尽管它不适用于空命令集),您总是可以执行ps $(pgrep cmd)...。

– Maciej Piechotka
13年5月1日14:18

#3 楼

理想的解决方案是BriGuy提供的解决方案

pgrep fnord 


,但是如果您不想这样做,则可以使用以下方法排除所有与grep匹配的行: />
ps aux | grep -v grep | grep "fnord"


评论


但是,如果我要查找的行是“ bash bash grep bash”,该怎么办?

– Sparr
13年4月30日在20:27

@Sparr然后,您应该使用最佳解决方案:pgrep或找到另一个;)

– RSFalcon7
2013年5月1日15:15



注意使用pgrep的名称长度限制。使用-f获取完整的路径名,否则您可能会发现匹配失败而使用了更长的名称。 -l也很好,可以列出匹配项

–尼尔·麦吉尔(Neil McGill)
2014年12月16日14:32

改进的变化。

–墨菲
19-10-11在8:04

#4 楼

不是最优雅的解决方案,但您可以执行以下操作:

$ ps aux | grep fnord | grep -v grep

评论


这是一个不好的答案!因为如果您的短语中有grep这个词。它不会显示该过程。例如,假设nano命令正在编辑一个名为foo_grep_bar.txt的文件。因此,有一个正在运行的进程:根14908 0.0 0.0 0.0 110012 1692 pts / 3 S + Oct31 0:00 nano foo_grep_bar.txt根据此答案,此操作将无效:$ ps aux | grep nano | grep -v grep因为文件名中包含grep字。

–纳比K.A.Z.
17-10-31在23:33

我更喜欢此方法,因为它比预期的答案更明确地表明其意图,并且除了一种情况外,其他方法均有效。

–samaspin
18 Mar 28 '18在11:20

根据superuser.com/a/409658/450260,您应该排除完整的grep选项,而不仅仅是grep,即$ ps aux | grep fnord | grep -v“ grep fnord”

–达沃斯
18年7月26日在7:22

改进的变化。

–墨菲
19-10-11在8:04

#5 楼

在zsh中,为grep fnord =(ps aux)

想法是,首先运行ps aux,将结果放入文件中,然后在该文件上使用grep。只是,我们没有文件,因为我们使用zsh的“进程替换”。应该是相同的。

对其他一些答案的一般评论。有些远远不够复杂和/或很难输入。这不仅是正确的问题,它也应该可用。但这并不意味着其中一些解决方案是不好的;只能将它们包装在微型UI中以使其可用。

评论


不知道zsh的进程替换,但是可以确定两个进程被称为一个接一个而不是并行吗?

–PaŭloEbermann
13年5月1日在10:17

@PaŭloEbermann:对于并行,是<(命令)。 grep grep =(ps aux)不显示任何行。

– Maciej Piechotka
2013年5月1日14:17

Zsh还可以“匹配” ps.print -l $ {(M)$ {(f)¨$(ps aux)¨}:#* fnord *}的输出。

– Friartek
19年3月9日在22:57

#6 楼


⚠这个答案是特定于GNU的。有关更通用的解决方案,请参见Wayne的答案。通过命令名称:

ps -C fnord


可以根据需要将其与BSD和POSIX样式的格式选项混合使用。有关完整列表,请参见ps手册页。

寻找其他内容吗?

如果您需要比精确搜索命令名称更高级的内容,请不要松懈希望!仍然可以在管道的fnord一侧进行此操作。我们要做的就是告诉-C从结果中排除ps进程:

ps -NC grep | grep 'fnord'


ps选择所有grep进程,而grep取消选择。这可用于搜索命令参数,命令名称的一部分或更复杂的正则表达式。

评论


这对于GNU ps很好,但是-C未由POSIX指定,并且在BSD上具有完全不同的含义

–埃里克·雷诺夫(Eric Renouf)
16年8月30日在18:02

没有BSD等效项真是令人really目结舌(这也意味着它不能在Mac上运行)。到目前为止,使用ps -C是所有方法中最简单的答案。

–克里斯托弗·亨特(Christopher Hunter)
18年11月9日在22:51

#7 楼

ps aux | grep $(echo fnord | sed "s/^\(.\)/[]/g")


评论


这看起来像一个IOCCC,但是对于unix命令行而不是C ^^ grep $(echo fnord)还不够吗?您还要求sed搜索并用其自身的值替换“ nord”中的每个字符? ^^恭喜。我敢打赌,我可以做更长的时间,但可能不会那么有趣^^

–奥利维尔·杜拉克(Olivier Dulac)
13年4月30日在16:26

抱歉,我的上述言论听起来令人反感(500万之后我无法编辑)...您的回答确实令人愉快,但我并没有试图让您看起来很糟。我真的认为您是故意这样做的^^

–奥利维尔·杜拉克(Olivier Dulac)
13年4月30日在16:31

抱歉,您的答案阅读起来真的很有趣(也很特别)。我的意思是pgrep -l $ 1;)

– yPhil
13年4月30日在16:48

@OlivierDulac:他不只是将第一个字符替换为它自己的值。他将其值替换为方括号中的值。 (那些方括号并不特殊,它们是字面意思。)基本上,他对Wayne Werner的回答进行了概括,因此可以编写在第一个字符周围放置方括号的过程。 +1

– LarsH
13年4月30日在18:02



ps aux | grep'[^]] fnord'可以避免这种体操。

–StéphaneChazelas
13年4月30日在20:21

#8 楼

与外壳无关的最简单方法是先将其存储在变量中:

 PS_OUTPUT="$(ps aux)"; echo "$PS_OUTPUT" |grep fnord
 


标注:@EmanuelBerg的grep fnord =(ps aux)答案是迄今为止最精美的,尽管它需要zsh。我曾在rc文件中短暂地使用过它,但是bash抱怨该语法,即使有条件应阻止对其进行求值。需要grep的参数:

 psl() {
  local PS_OUTPUT="$(ps auxww)"
  echo "${PS_OUTPUT%%$'\n'*}" >&2  # title, in stderr to avoid pipes
  echo "${PS_OUTPUT#*$'\n'}" |grep -i "${@:-^}"
}
 


代码遍历,每行代码一个项目符号:


捕获详细的ps输出(在local变量中,以便函数返回时消失)
以标准错误显示第一行(标题),以便进一步得到结果过滤后不会影响标题。替换内容为:取$PS_OUTPUT并在第一个换行符之后删除所有内容(正则表达式等效:s/\n.*$//msg)。这可以防止我们对标题进行grep显示
显示除第一行以外的所有内容(正则表达式:ps),并用s/^.*\n//m对其内容进行grep显示(不区分大小写),并将所有参数传递给该函数(在这种情况下)不带参数的-i,它匹配任何行的开头以匹配所有内容)


#9 楼

我的答案是在“ 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=[^]];
    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
}


#10 楼

这是grep -v grep解决方案的扩展版本,可以过滤掉所有运行时间不超过一秒钟的grep进程,这是对“仅丢弃grep的所有出现”的改进。 />分别


$ ps -ef | grep -vw "00:00:00 grep" | grep <searchTerm>


这可能无法移植,并且取决于本地ps命令的实际输出格式。 >为方便起见,您可能希望将其与彩色的grep输出结合使用:

$ ps aux | grep -vw "0:00 grep" | grep <searchTerm>


#11 楼

也许这次是时候使用真实的序列了。

ps aux >f && grep tmpfs <f


丑陋,因为会有一个文件f,但这并不是我的错,因为顺序语法没有语法想要使用先前运行的进程的输出。

建议使用顺序运算符的语法:

ps aux ||| grep tmpfs


评论


普通人无法轻松过滤流,这几乎不是精英阶层以序列为基础的原因。这将是计算方面的倒退。

–触角
14年8月18日在20:27

@ A-B-B en.wikipedia.org/wiki/Communicating_sequential_processes的运算符比在Thompson shell中结尾的运算符还要多。可能只是一个顺序操作符,该操作符在退出后立即将其结果传达给顺序中的下一个进程。通过提供额外的运算符来“向后退一步”似乎有些苛刻。

–Anne van Rossum
2014年8月19日在7:09



链接很好,但是相对于并行处理,顺序处理在CPU和内存(或磁盘)的使用上都更差。在这种情况下,如果我必须在grep之前先存储所有ps输出,那么我将使用更多的内存(或磁盘)更长的时间。

–触角
14年8月19日在19:37



#12 楼

正如其他人所说,pgrep命令将根据名称和其他属性返回进程的PID(进程ID)。例如,

pgrep -d, -u <username> <string>


将为您提供PID,以名称(由用户<username>运行)匹配的所有进程的逗号(,)分隔。您可以在使用-x开关之前仅返回完全匹配项。

如果要获取有关这些进程的更多信息(如从ps运行aux选项所暗示的),则可以使用-p选项ps,根据PID进行匹配。因此,例如,

ps up $(pgrep -d, -u <username> <string>)


将给出pgrep命令匹配的所有PID的详细信息。

评论


如果pgrep返回空集,则ps失败。我有一个基于您的答案,并试图解决此问题。

–触角
14年8月19日在17:00

#13 楼

这是一个简单的示例,用于查找用户名的ssh-agent的PID,而不显示grep进程本身的PID:

ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print  ;}'


如果您想例如杀死当前用户的ssh-agent,则可以使用以下命令:

kill `ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print ;}'`


要创建方便的别名,请在您的〜/ .bashrc或〜/ .zshrc文件中添加以下代码:

function function1 () {
    ps xu | grep ".*" | awk '{print " "" ";}'
}
alias mygrep="function1"


并在此处使用别名来强迫所有人学习正则表达式的示例:

. /etc/profile #to make alias usable
mygrep ${USER} ${PROCESS_PATH}
mygrep ${USER} "[f]nord"
mygrep "[f]nord"
mygrep ".*[s]shd"


PS我只在Ubuntu和Gentoo上测试了这些命令。

评论


(1)问题并不是说用户正在寻找自己的过程之一,而是用户可能不知道他正在寻找的过程的所有者。 (2)就像这个答案一样,如果您说“ $ {USER}。* / usr / bin / ssh-agent”,它仍然会失败。之所以有效,是因为您说过[];也就是说,您只是在使用接受答案的机制。您不妨只是grep“ [s] sh-agent”。

– G-Man说“恢复莫妮卡”
2015年11月6日14:27

你是对的。 (1)我分享了一些有用的信息,因为我偶尔会遇到此页面(2)是的,我像接受的答案一样使用了正则表达式。 (3)我将答案更新为与接受的答案相同,因为更好,但是我也展示了如何在提供或不提供用户名的情况下使用别名。 (4)还显示了如何定义函数,虽然不是必需的,但是它以有趣的方式工作,因为$ 1和$ 2不重叠。 Thx#G-Man

–康斯坦丁·扎戈尔斯基(Constantin Zagorsky)
2015年11月7日在16:30

#14 楼

使用-x(完全匹配)选项对我有用。我将它与-f(完整的命令行)结合使用,因此我的过程可以精确地与:

pgrep -x -f "path_i_used_when_starting/cmd params_i_used"


评论


谁在进行过分否决的人会自我解释?多年来,我一直在努力为我解决这个问题。

–moodboom
19年4月13日在18:37

#15 楼

您只需在.bashrc中定义一个ALIAS即可轻松做到,就像这样:

alias grep='grep -v grep | grep'


评论


不知道谁拒绝投票或为什么投票,但这可以让您充分利用pgrep不能使用的ps。

–opticyclic
16年11月27日,0:05

这不仅无意中排除了其他grep进程;在其他情况下,它也会中断grep的使用。尝试echo我爱grep | grep的爱。

– Trosos
17年5月21日在22:54

@trosos近11年以来,我一直在* nixing ..且从未使用过这种模式...也许明年,-谁知道呢。

–a20
18年3月29日在11:08