Apa cara yang tepat untuk memeriksa apakah PID berjalan?

12

Saya punya .pidfile, dan saya perlu memeriksa apakah prosesnya berjalan. Sejauh ini saya menemukan dua opsi

kill -0 `cat something.pid`

yang mencetak kesalahan jika pid tidak berjalan. Saya tahu ini dapat dialihkan ke /dev/null, tetapi itu membuat saya berpikir bahwa ini bukan solusi terbaik.

Solusi kedua adalah menggunakan ps, yang juga mencetak pada STDOUT

ps -ef `cat something.pid`

Apakah normal untuk mengarahkan output ke /dev/nulldan hanya menggunakan kode status yang dikembalikan, atau itu pertanda bahwa saya melakukan sesuatu yang salah dan saya perlu perintah yang berbeda?

Jakub Arnold
sumber
5
Gunakan kill -0seperti standar (POSIX) -compliant.
Anders

Jawaban:

9

untuk sebagian besar distro linux, enumerasi / proc / {pid} adalah cara yang baik untuk mendapatkan informasi tentang proses yang sedang berjalan, dan biasanya bagaimana perintah userspace seperti "ps" berkomunikasi dengan kernel. Jadi misalnya bisa Anda lakukan;

[ -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

Sunting: Anda harus memeriksa bahwa kpid disetel, tetapi ini lebih berguna karena akan mengembalikan "tidak ada" untuk tidak disetel $ {kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"
Tom H
sumber
@SteveMuster Ini akan membuat jawaban khusus Linux. Tidak ada / proc di OSX. Dan saya pikir tidak ada / proc pada BSD.
ash
Catatan dengan ini Anda harus memastikan ${kpid}ada
Wilf
@Apakah saya mengeditnya, sehingga mengembalikan "proses tidak ada" untuk $ $ kpid yang belum disetel
Tom H
Terima kasih - Saya sedang membuat skrip yang memeriksa PID menggunakan metode yang serupa dan tidak berfungsi sampai saya menemukan ini masalahnya :)
Wilf
6

Seperti yang dicatat Anders, Anda harus menggunakannya kill -0untuk kepatuhan POSIX.

Pada sistem Linux, Anda juga dapat memeriksa keberadaan file di sistem file / proc, misalnya,

-f /proc/$(cat something.pid)/status
cjc
sumber
1

Jika ini dalam skrip (yang saya asumsikan adalah kasus karena Anda khawatir tentang mencetak ke stdout) maka berikut ini adalah bagaimana Anda bisa melakukannya:

if ps -p $(cat something.pid) > /dev/null 2>&1
then
    kill $(cat something.pid)
else
    # Deal with the fact that the process isn't running
    # i.e. clear up the pid file
fi

The ps -ppenampilan untuk proses dengan pid ditentukan dalam something.pid (yang $()sintaks adalah sedikit versi yang lebih baru dari backtick tersebut. Backtick perlu melarikan diri dalam keadaan tertentu yang bentuk baru tidak). Itu2>&1 pengalihan stderr untuk perintah itu juga.

Jika ps -pperintah tidak menemukan proses dengan PID itu keluar dengan kesalahan> 0 dan elsedijalankan. Kalau tidak, killpernyataan. Anda dapat meniadakan hal di atas jika Anda ingin dengan melakukan:

if ! ps -p ...

Semoga itu menjawab pertanyaan Anda. Tentunya berhati-hati dan banyak menguji ketika menggunakan perintah berbahaya seperti kill.

webtoe
sumber
1

Berikut ini beberapa opsi:

  • Jika Anda menulis skrip init (misalnya skrip yang akan ditempatkan /etc/init.d/) dan jika Anda menggunakan distro berbasis Debian, Anda sebaiknya menggunakan start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    Anda harus mendapatkan kode keluar 0 jika sedang berjalan.
  • Anda dapat menggunakan pgrep dan pkill dari procpspaket:
    pgrep --pidfile $PIDFILE
Jolly Roger
sumber
0

Jika Anda memiliki file pid, Anda dapat menggunakan pgrep untuk memeriksa apakah proses sedang berjalan:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi
Dima L.
sumber