Làm thế nào để ngăn chặn báo cáo về quy trình của riêng mình?


52
$ 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

Có cách nào để ngăn chặn quá trình cuối cùng (nghĩa là grep đã được bắt đầu cùng lúc với lệnh ps của tôi) được báo cáo không?

(Tôi bắt đầu cố gắng đưa ra một biểu thức chính tả phù hợp với nghĩa đen nhưng không khớp với chính nó, nhưng dường như, ừm, không phải là cách tiếp cận đúng đắn ...)

Câu trả lời:


14

Câu trả lời của tôi là một biến thể của câu trả lời điển hình cho việc tìm kiếm "foobar" trong psdanh sách. Đối số của tôi "-A" "ps"là dễ mang theo hơn "aux", tôi tin, nhưng sự thay đổi này không liên quan đến câu trả lời. Câu trả lời điển hình như thế này:

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

Thay vào đó tôi sử dụng mẫu này:

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

Ưu điểm chính là việc viết các tập lệnh dựa trên các mẫu này dễ dàng hơn vì bạn chỉ cần nối một chuỗi tĩnh [^]]với bất kỳ mẫu nào bạn đang tìm kiếm. Bạn không cần phải loại bỏ chữ cái đầu tiên của chuỗi sau đó chèn nó vào giữa các dấu ngoặc vuông và sau đó nối lại chuỗi đó lại với nhau. Khi viết kịch bản trong shell, đơn giản hơn là chỉ cần dán [^]]trước mẫu mà bạn đang tìm kiếm. Cắt chuỗi trong Bash là một điều xấu xí, vì vậy biến thể của tôi tránh điều đó. Biến thể này cho biết hiển thị các dòng trong đó mẫu khớp với KHÔNG CÓ khung vuông vuông bên phải hàng đầu]. Vì mẫu tìm kiếm để loại trừ một khung vuông thực sự thêm khung vuông vào mẫu nên nó sẽ không bao giờ khớp với chính nó.

Vì vậy, bạn có thể viết một psgreplệnh di động như sau. Ở đây, tôi thực hiện một số khoản trợ cấp cho sự khác biệt giữa Linux, OS X BSD và các loại khác. Điều này thêm các tiêu đề cột từ ps, cung cấp một tùy chỉnh nhiều hơnpsđịnh dạng phù hợp với nhu cầu của tôi hơn và hiển thị các quy trình liệt kê thêm, rộng hơn để không có đối số dòng lệnh nào bị bỏ lỡ. Vâng, hầu hết không được bỏ lỡ. Java là Java, nó thường thực hiện mọi thứ theo cách tồi tệ nhất có thể, do đó, một số dịch vụ java sẽ chạy qua độ dài tối đa được phép của các đối số mà bảng quy trình sẽ theo dõi. Tôi tin rằng đây là 1024 ký tự. Độ dài đơn lệnh cho phép bắt đầu một quy trình dài hơn nhiều, nhưng bảng quy trình nhân không bận tâm theo dõi bất cứ thứ gì có độ dài trên 1K. Khi lệnh được bắt đầu, tên lệnh và danh sách đối số không cần thiết, vì vậy những gì được lưu trữ trong bảng quy trình chỉ là thông tin.

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
}

Nhược điểm là điều này thực sự sẽ khớp với một char nhiều hơn (ở phía trước) so với mẫu ban đầu. Ví dụ, điều này sẽ không bao giờ phù hợp với PID. Và có thể là một chút sai lệch khi sử dụng với grep --colour.
Tonin

67

+1 cho câu trả lời ngắn gọn @jamened, tuy nhiên OP có thể cần một số lời giải thích:

ps | grep "[d]jango"

Sử dụng regex đó, bạn sẽ khởi chạy một quy trình mà chuỗi ps của nó không khớp với chính nó, vì regex khớp "django"và không "[d]jango". Bằng cách đó, bạn sẽ loại trừ quy trình có chuỗi "[d] jango" mà trong trường hợp này là grep; Điều tương tự có thể được áp dụng cho pgrep, egrep, awk, sed, v.v ... bất kỳ lệnh nào bạn đã sử dụng để xác định regex.

Từ người đàn ông 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.

2
Mát mẻ. Tôi thực sự khá thoải mái với regex nhưng không thể ngay lập tức nghĩ ra cách ngăn chặn sự phù hợp với chính quy. Kèm theo một chữ cái trong ngoặc vuông có ý nghĩa hoàn hảo. (Bao gồm những thứ như [^!] Cũng sẽ hoạt động ...)
Steve Bennett

1
Thật tuyệt và xảo quyệt.
tro

Đối với trường hợp cụ thể 'ps', tôi sử dụng '[]' ở phía trước tên quy trình tôi đang tìm kiếm. Sau đó, tôi không cần phân tích tên quy trình đặc biệt cho biểu thức chính quy, nhưng nó vẫn khớp.
Neromancer

@hmontoliu Nó không hoạt động chẳng hạn : ps aux | grep [s]cript1. Bạn có thể giúp nhận xét về giải pháp?
SOUser

@hmontoliu Lỗi của tôi. Có vẻ như dòng này được hiển thị vì các tìm kiếm trước đó ...
SOUser

30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


Thêm dung lượng nếu bạn cần grep one char:ps aux| grep "[Z] "
AD

@jamened Nó không hoạt động ví dụ: ps aux | grep [s]cript1hoặc ps aux | grep [s]cript2. Dòng grep vẫn được hiển thị. Bạn có thể giúp nhận xét về giải pháp?
SOUser

@jamened Lỗi của tôi. Có vẻ như dòng này được hiển thị vì các tìm kiếm trước đó ...
SOUser

18

Sử dụng pgrep thay thế: pgrep -lf django


Như thường lệ, tôi quên đề cập đến nền tảng (OS X trong trường hợp này). Có lẽ pgrep hoạt động trên các linux khác nhau.
Steve Bennett

Tôi không đồng ý, @ramruma. Tôi đến với chủ đề này chính xác bởi vì pgrepcung cấp cho tôi chính xác vấn đề này. Nhưng tôi phải nói rằng tôi đang thử nghiệm nó trong CygWin (nơi pskhông thể hiển thị dòng lệnh đầy đủ của quy trình).
Sopalajo de Arrierez

Hướng dẫn sử dụng "Quá trình pgrep hoặc pkill đang chạy sẽ không bao giờ tự báo cáo là khớp." Và thực sự tôi chưa thấy nó làm như vậy.
deltab

Tôi vừa mới giải quyết một vấn đề mà tôi nghĩ pgreplà phù hợp với chính nó. Hóa ra nó khớp với tên của bashtệp script tôi đang chạy nó. Thêm -xcố định nó, sau đó nó thực hiện một khớp chính xác trên tên lệnh.
andynormancx

11

Đợi đã, cái này hoạt động:

ps | grep django | grep -v grep

7
Chỉ khi dòng lệnh quy trình không bao gồm một cách hợp pháp grep, mà bạn không thể tính đến trong trường hợp chung.
một CVn

8

ps -d | grep django

từ người đàn ông ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

vẫn hiển thị grep trên của tôi ...
Kevin

Đúng, nó hoạt động với tôi trên OS X.
Steve Bennett

Không hoạt động tốt trên Linux.
Acumenus

Tổng quát hơn, các tùy chọn psnổi tiếng là không di động, vì vậy không có thông tin về nền tảng này là gì, câu trả lời này không hữu ích lắm. Hơn nữa, điều này rõ ràng là không thỏa đáng khi bạn không chắc chắn rằng quy trình bạn đang tìm kiếm không phải là một nhà lãnh đạo quy trình (nghĩa là điều này có thể giúp ích nếu mục tiêu của bạn là một daemon, nhưng nói chung là không).
tripleee

Thật buồn cười, trên Mac, điều này dường như chỉ hiển thị quá trình grep và lọc mọi thứ khác.
Christopher Hunter
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.