如何使用标头grep ps输出


26

如何在标头到位的情况下grep PS输出?

这两个过程组成了在我的服务器上运行的应用。

root     17123 16727  0 16:25 pts/6    00:00:00 grep GMC
root     32017     1 83 May03 ?        6-22:01:17 /scripts/GMC/PNetT-5.1-SP1/PNetTNetServer.bin -tempdir /usr/local/GMC/PNetT-5.1-SP1/tmpData -D

6-22:01:17意味着它已经运行了6天?我正在尝试确定进程已运行多长时间...

第二列是进程ID吗?因此,如果我这样做kill 32017会杀死第二个进程?

Answers:


37
ps -ef | egrep "GMC|PID"

更换“ GMC”并ps根据需要进行开关。

输出示例:

root@xxxxx:~$ ps -ef | egrep "disk|PID"

UID        PID  PPID  C STIME TTY          TIME CMD
paremh1  12501 12466  0 18:31 pts/1    00:00:00 egrep disk|PID
root     14936     1  0 Apr26 ?        00:02:11 /usr/lib/udisks/udisks-daemon
root     14937 14936  0 Apr26 ?        00:00:03 udisks-daemon: not polling any devices

8
添加一些有关“为什么”有效的信息会很好。
伊利亚·林恩

2
不,这是用户的一项练习。
Hyppy

@ElijahLynn它与标题中的文本匹配-在这种情况下为PID。但是您可以将其替换为UID,PTIME或标题中的任何其他内容……
Ben Creasy

5
因此ps -e选择所有进程,并且ps -f是显示列标题的全格式列表。然后,我们通过管道将列标题发送到egrep,它是grep的扩展,并允许管道|具有特殊含义,即OR(此OR that)。因此,最终要匹配列标题中的PID和重要的输出行。
伊利亚·林恩

我必须在Ubuntu 16.04中的egrep / grep -E命令中使用简单的引号,例如: ps -ef | grep -E 'GMC|PID'
Vlax

13

感谢geekosaur,我想根据您的需求使用此命令,而不是单独的命令:

ps -ef | head -1; ps -ef | grep "your-pattern-goes-here"

棘手的是利用“;” 外壳程序支持将命令链接起来。


比接受的答案更干净,更可靠。它不会断言标头中包含PID,也不会增加grep字符串的复杂性。
7yl4r

2
哦等等...你已经ps -ef重复了。更好的是ps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r

@ 7yl4r从未使用过该shell功能。我尝试了改进的命令,效果很好!学会了,:)
刘德华

3
已找到有关此技术的解释,称为“分组命令”,以供其他人好奇,请参阅:gnu.org/software/bash/manual/html_node/Command-Grouping.html
Vic Lau

@ 7yl4r很棒的技术!我正在寻找如何不重复该命令。分组的命令甚至可以通过管道传递:ps -ef | { head -1; grep "pattern" | head -5; }。如果grep-ed模式有很多结果,则很有用!
沉迷

6

第二列是进程ID;第四点是流程创建的时间(通常是程序启动的时间,但并非总是如此;请考虑execve()和朋友);6th是消耗的CPU时间。因此它已经运行了8天,并使用了将近7天的CPU时间,我认为这令人担忧。

在相同的调用中获得标头充其量是很棘手的。我会单独做ps | head -1。您可能会考虑使用ps自己的选择方法或类似的pgrep替代方法grep,实际上并不是为了通过标头而设计的。


什么83
网络

当前进程优先级,它基于其过去的CPU和I / O使用率以及用户或系统分配的nice值。数字越小优先级越高。在这种情况下,grep优先级为0,因为它在磁盘读取时被阻止并屈服于写入其输出;而优先级为0,PNetTNetServer.bin因为它始终用尽其时间片而不被阻止。(日程安排很复杂,具体取决于所使用的日程安排。)
geekosaur 2011年

5

egrep解决方案既简单又有用,但是当然,您需要依赖始终包含“ PID”(尽管这是一个合理的假设)的标头以及在其他地方不会出现的相同字符串。我猜想这足以满足您的需求,但是如果有人想要替代产品,请务必使用sed。

Sed让您只说“先打印第一行,然后打印任何包含该模式的行”。例如:

ps auxwww | sed -n '1p; /PROCESS_NAME_TO_SEARCH/p;'

添加/sed -n/d;到过滤器sed本身:

ps auxwww | sed -n '1p; /sed -n/d; /PROCESS_NAME_TO_SEARCH/p;'

/sed -n/d是不正确的。sed -n您可能要打印一些现有的命令。绝招是用sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'。;-)注意[]搜索字符串中的任何字符。
anishsane

4

更简单的选择: ps -ef | { head -1; grep GMC; }

用标头显示的行数替换该数字。


1
我喜欢这种方法,但是命令最后需要另一个分号。ps -ef | { head -1; grep GMC; }。我也喜欢以下功能:function pgrep() { ps -ef | { head -1; grep $@; } }
Brett

1

你可以用pgrep获取pid

pgrep PNetTNetServer

然后将ps与pid一起使用

ps u 12345

甚至将两者合并为一个命令

ps u `pgrep PNetTNetServer`

这将仅显示所需的行,并包含标题。


0

我写了一个小的Perl程序

  • 第一行和所有匹配的行(如果有匹配项),或
  • 没有,如果没有匹配项。

我最常像那样使用它ps | 1andre GMC,但它也可以使用文件参数(每个文件都提供自己的标题行,用于匹配该文件中的行)。



#!/usr/bin/perl

#
# 1andre <regexp> [<file> ...]
#
#   1 -           first ({1}st)
# and -                  {and}
#  re - (lines matching) {re}gexp
#
# If no <files> are given (or "-" is given as a <file>) stdin is
# used.
#
# If any lines from each <file> match the <regexp>, print the
# first line from that <file> and all the matching lines from
# that <file>.
#

use strict;
use warnings;

if(scalar @ARGV < 1) {
  printf STDERR "usage: %s <regexp> [<file> ...]\n", $0;
  exit 1;
}

my $re = shift;
my $header;

while(<>) {
  if($. == 1) {
    $header = $_;
  } elsif(m/$re/) {
    if(defined $header) {
      print $header;
      undef $header;
    }
    print;
  }
} continue {
  # close resets $. when we get to the end of each file that <> is processing
  close ARGV if eof;
}
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.