Làm thế nào để grep ps đầu ra với các tiêu đề


26

Làm cách nào tôi có thể grep đầu ra PS với các tiêu đề tại chỗ?

Hai quá trình này tạo nên một ứng dụng chạy trên máy chủ của tôi ....

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:17nghĩa là nó đã chạy được 6 ngày? Tôi đang cố gắng xác định thời gian quá trình đã chạy ...

Là cột thứ 2 là id quá trình? Vì vậy, nếu tôi làm điều kill 32017đó sẽ giết quá trình thứ 2?

Câu trả lời:


37
ps -ef | egrep "GMC|PID"

Thay thế "GMC" và pschuyển đổi khi cần thiết.

Ví dụ đầu ra:

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
Sẽ tốt hơn nếu thêm một số thông tin về 'tại sao' điều này hoạt động.
Elijah Lynn

2
Không, đó là một bài tập cho người dùng.
Hyppy

@ElijahLynn Nó khớp với văn bản trong tiêu đề - trong trường hợp này là PID. Nhưng bạn có thể đổi nó lấy UID, PTIME hoặc bất cứ thứ gì khác trong tiêu đề ...
Ben Creasy

5
Vì vậy, ps -echọn tất cả các quy trình và ps -flà danh sách định dạng đầy đủ hiển thị các tiêu đề cột. Sau đó, chúng tôi đặt các tiêu đề cột và đầu ra thành egrep, được mở rộng grep và cho phép đường ống |có một ý nghĩa đặc biệt, đó là OR (cái này HOẶC cái đó). Vì vậy, cuối cùng bạn phù hợp với PID trong các tiêu đề cột cộng với các dòng đầu ra quan trọng.
Elijah Lynn

Tôi đã phải sử dụng dấu ngoặc kép đơn giản trong lệnh egrep / grep -E trong Ubuntu 16.04, ví dụ: ps -ef | grep -E 'GMC|PID'
Vlax

13

Nhờ geekizard, tôi muốn sử dụng lệnh này cho nhu cầu của bạn, thay vì một lệnh riêng biệt:

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

Khó khăn là sử dụng dấu ";" được hỗ trợ bởi shell để xâu chuỗi lệnh.


Điều này sạch sẽ và mạnh mẽ hơn câu trả lời được chấp nhận. Nó không khẳng định rằng tiêu đề có PID trong đó và không thêm độ phức tạp vào chuỗi grep.
7yl4r

2
oh chờ đã ... bạn đã ps -eflặp đi lặp lại thậm chí tốt hơn làps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r

@ 7yl4r không bao giờ sử dụng khả năng vỏ đó. Tôi đã thử lệnh cải tiến của bạn, hoạt động hoàn hảo! Đã học, :)
Vic Lau

3
Tìm thấy lời giải thích về kỹ thuật này, được gọi là 'Nhóm lệnh', vì sự tò mò của người khác, hãy xem: gnu.org/software/bash/manual/html_node/Command-Grouping.html
Vic Lau

@ 7yl4r kỹ thuật tuyệt vời! Tôi đã tìm cách để không lặp lại lệnh. Lệnh được nhóm thậm chí có thể được dẫn đường : ps -ef | { head -1; grep "pattern" | head -5; }. Hữu ích nếu mẫu grep-ed có nhiều kết quả!
nghiện

6

Cột thứ hai là id quá trình; Thứ 4 là khi quá trình được tạo ra (đây thường là thời gian chương trình của bạn bắt đầu, nhưng không phải lúc nào cũng vậy; xem xét execve()và bạn bè); Thứ 6 là lượng thời gian CPU tiêu thụ. Vì vậy, nó đã chạy được 8 ngày và sử dụng gần 7 ngày thời gian CPU, điều mà tôi cho là đáng lo ngại.

Nhận tiêu đề trong cùng một lời mời là khó khăn nhất; Tôi chỉ muốn làm riêng ps | head -1. Bạn có thể cân nhắc sử dụng pscác phương pháp lựa chọn của riêng mình hoặc một cái gì đó như pgrepthay vì grep, không thực sự được thiết kế để vượt qua các tiêu đề.


Là gì 83?
Webnet

Ưu tiên quá trình hiện tại, dựa trên việc sử dụng CPU và I / O trước đây của nó và nicegiá trị được gán bởi người dùng hoặc hệ thống . Số nhỏ hơn được ưu tiên cao hơn. Trong trường hợp này, grepmức độ ưu tiên là 0 vì nó bị chặn trên đĩa đọc và mang lại kết quả đầu ra và PNetTNetServer.binlà một số lượng lớn vì nó luôn sử dụng hết thời gian của nó mà không bị chặn. (Lập lịch trình rất phức tạp và các chi tiết sẽ phụ thuộc vào lịch trình chính xác đang được sử dụng.)
geekizard

5

Giải pháp egrep rất đơn giản và hữu ích, nhưng tất nhiên bạn phụ thuộc vào tiêu đề luôn chứa 'PID' (tuy nhiên, một giả định hợp lý hơn) và cùng một chuỗi không xuất hiện ở nơi khác. Tôi đoán điều này là đủ cho nhu cầu của bạn, nhưng trong trường hợp ai đó muốn một sự thay thế thì có sed.

Sed cho phép bạn chỉ cần nói "in dòng đầu tiên, sau đó bất kỳ dòng nào chứa mẫu". Ví dụ:

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

Thêm /sed -n/d;vào bộ lọc sed chính nó:

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

/sed -n/dKhông đúng. Một số lệnh hiện có có thể có sed -n, mà bạn muốn in. Thủ thuật là sử dụng sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Lưu ý []xung quanh bất kỳ ký tự nào trong chuỗi tìm kiếm.
anishsane

4

thay thế dễ dàng hơn: ps -ef | { head -1; grep GMC; }

thay thế số bằng số dòng mà tiêu đề của bạn được hiển thị trên đó.


1
Tôi thích cách tiếp cận này nhưng lệnh cần một dấu chấm phẩy khác ở cuối. ps -ef | { head -1; grep GMC; }. Ngoài ra tôi thích nó trong một chức năng như sau:function pgrep() { ps -ef | { head -1; grep $@; } }
Brett

1

bạn có thể lấy pid với pgrep

pgrep PNetTNetServer

và sau đó sử dụng ps với pid

ps u 12345

hoặc thậm chí kết hợp cả hai thành một lệnh

ps u `pgrep PNetTNetServer`

Điều này sẽ chỉ hiển thị dòng bạn muốn, và bao gồm tiêu đề.


0

Tôi đã viết một chương trình Perl nhỏ sẽ in

  • dòng đầu tiên và tất cả các dòng khớp nhau, nếu có bất kỳ kết quả khớp nào, hoặc
  • Không có gì, nếu không có trận đấu.

Tôi thường sử dụng nó như thế ps | 1andre GMC, nhưng nó cũng có thể lấy các đối số tệp (mỗi tệp cung cấp dòng tiêu đề riêng cho các kết quả khớp trên các dòng từ tệp đó).



#!/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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.