Tại sao pidof và pgrep lại cư xử khác nhau?


8

Tôi có một tập lệnh init /etc/init.d/myserviceđể khởi tạo một dịch vụ như thế này:

...
start() {
  ...
  daemon /usr/sbin/myservice
  ...
}

stop() {
  ...
  pgrep myservice
  pidof myservice
  ps -ef | grep myservice
  ...
}

Và khi tôi cố gắng dừng dịch vụ, đây là đầu ra:

10000 10001
10000
root      10000     1  0 09:52 ?        00:00:02 /usr/sbin/myservice
root      9791   9788  0 10:06 pts/1    00:00:00 /bin/sh /sbin/service myservice stop
root      10001  9791  1 10:06 pts/1    00:00:00 /bin/sh /etc/init.d/myservice stop 
root      9805   9796  0 10:06 pts/1    00:00:00 grep myservice

Đây có phải là mong đợi? Tại sao pidofchỉ trả lại đúng PID của dịch vụ mà tôi muốn dừng và pgreptrả lại PID dịch vụ và PID của tập lệnh init? Tôi có thể dựa vào đó pidofsẽ luôn bỏ qua PID từ tập lệnh init không?

Câu trả lời:


7

pidof = tìm ID tiến trình của chương trình đang chạy

Pidof tìm thấy id quá trình (pids) của các chương trình được đặt tên. Nó in những id đó trên đầu ra tiêu chuẩn. Chương trình này nằm trên một số hệ thống được sử dụng trong các kịch bản thay đổi cấp độ chạy, đặc biệt là khi hệ thống có cấu trúc RC giống như System-V.

sysadmin@codewarden:~$ pidof apache2
5098 5095 5094 5092

pgrep = tra cứu hoặc xử lý tín hiệu dựa trên tên và các thuộc tính khác, pgrep xem qua các quy trình hiện đang chạy và liệt kê ID quy trình phù hợp với tiêu chí lựa chọn.

sysadmin@codewarden:~$ pgrep apache2
5092
5094
5095
5098

pgrep, (p) = process, grep= grep in các dòng khớp

Bạn muốn biết thêm về pgrep & pidof? Chỉ cần chạy trong thiết bị đầu cuối như

# man pidof
# man pgrep

1
Aha, đó là lý do tại sao pidofkhông trở lại 10001, bởi vì chương trình là sh, không?
Pigueiras

yeap, bạn đúng
Babin Lonston

0

Tôi nghĩ bạn không nên dựa vào pidof, nó có thể khiến chương trình của bạn thất bại. Một ví dụ đơn giản với supervisordchương trình:

% cuonglm at ~
% ps -ef | grep supervisord
root      8512     1  0 16:53 ?        00:00:00 /usr/bin/python /usr/bin/supervisord
cuonglm   8584  7688  0 17:00 pts/0    00:00:00 grep --color=auto supervisord
% cuonglm at ~
% pidof supervisord
% cuonglm at ~
% 

Bạn có thể thấy, supervisordthực sự được gọi bởi trình thông dịch python, gây ra pidoflỗi:

#! /usr/bin/python                                                            
# EASY-INSTALL-ENTRY-SCRIPT: 'supervisor==3.0a8','console_scripts','supervisord'
__requires__ = 'supervisor==3.0a8'                                            
import sys                                                                    
from pkg_resources import load_entry_point                                    

if __name__ == '__main__':                                                    
    sys.exit(                                                                 
        load_entry_point('supervisor==3.0a8', 'console_scripts', 'supervisord')()
    )

Nhưng trong trường hợp này tôi có thể dựa vào nó không?, Tôi không sử dụng trình thông dịch để thực thi chương trình (nó là một tệp nhị phân thực thi).
Pigueiras

Tất nhiên. Nhưng tôi nghĩ cách tốt là sử dụng killproc. Tại sao bạn không sử dụng này trong khi bạn haved sử dụng daemontrong startchức năng?
cuonglm

Bởi vì tôi muốn có được PID để giết những đứa trẻ của quy trình, tôi đã sử dụng killprocđể giết chính quá trình đó.
Pigueiras

Tại sao bạn phải làm điều đó? nếu bạn giết parent process, nó child processcũng sẽ chết.
cuonglm

Không, tôi không nghĩ vậy: stackoverflow.com/questions/8533377/ trên
Pigueiras

0

Các pidoflệnh bỏ qua kịch bản, trừ khi bạn bao gồm các -xtùy chọn. Ngoài ra, an toàn nhất là bao gồm đường dẫn đầy đủ trên lệnh pidof, như trong:

killme=$(pidof -x /usr/bin/supervisord)
      *instead of*
killme=$(pidof -x supervisord)

điều này giảm thiểu cơ hội phù hợp với một số quy trình khác.

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.