Mengapa pidof dan pgrep berperilaku berbeda?

8

Saya memiliki skrip init /etc/init.d/myserviceuntuk menginisialisasi layanan seperti ini:

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

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

Dan ketika saya mencoba menghentikan layanan, ini adalah output:

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

Apakah ini yang diharapkan? Mengapa pidofmengembalikan hanya PID yang benar dari layanan yang ingin saya hentikan dan pgrepmengembalikan PID layanan dan PID dari skrip init? Bisakah saya mengandalkan itu pidofakan selalu mengabaikan PID dari skrip init?

Pigueiras
sumber

Jawaban:

7

pidof = menemukan ID proses dari program yang sedang berjalan

Pidof menemukan id proses (pers) dari program-program yang disebutkan. Ini mencetak id itu pada output standar. Program ini pada beberapa sistem yang digunakan dalam skrip perubahan run-level, terutama ketika sistem memiliki struktur rc seperti System-V.

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

pgrep = mencari atau memproses sinyal berdasarkan nama dan atribut lainnya, pgrep melihat melalui proses yang sedang berjalan dan mencantumkan ID proses yang sesuai dengan kriteria pemilihan.

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

pgrep, (p) = proses, grep= grep mencetak garis yang cocok

Ingin tahu lebih banyak tentang pgrep & pidof? Jalankan saja di terminal sebagai

# man pidof
# man pgrep
Babin Lonston
sumber
1
Aha, itu sebabnya pidoftidak kembali 10001, karena programnya sh, bukan?
Pigueiras
ya, benar
Babin Lonston
0

Saya pikir Anda tidak harus bergantung pada pidof, itu dapat menyebabkan program Anda gagal. Contoh sederhana dengan supervisordprogram:

% 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 ~
% 

Anda dapat melihat, supervisordsebenarnya disebut oleh python interpreter, menyebabkan pidofkegagalan:

#! /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')()
    )
cuonglm
sumber
Tetapi dalam hal ini saya dapat mengandalkannya bukan ?, saya tidak menggunakan juru bahasa untuk menjalankan program (ini adalah biner yang dapat dieksekusi).
Pigueiras
Tentu saja. Tapi saya pikir cara yang baik adalah menggunakan killproc. Mengapa Anda tidak menggunakan ini saat Anda haved digunakan daemondi startfungsi?
cuonglm
Karena saya ingin mendapatkan PID untuk membunuh anak-anak dari proses, saya gunakan killprocuntuk membunuh proses itu sendiri.
Pigueiras
Kenapa kamu harus melakukan itu? jika Anda membunuh parent process, itu child processakan mati juga.
cuonglm
Tidak, saya tidak berpikir begitu: stackoverflow.com/questions/8533377/…
Pigueiras
0

The pidofperintah mengabaikan script kecuali jika Anda termasuk -xpilihan. Juga, paling aman untuk memasukkan path lengkap pada perintah pidof, seperti pada:

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

ini meminimalkan kemungkinan pencocokan beberapa proses lainnya.

John Hascall
sumber