GNU/Linux >> Belajar Linux >  >> Linux

Cara mendapatkan pid dari proses yang baru saja dimulai

Solusi 1:

Apa yang bisa lebih sederhana dari echo $! ? Sebagai satu baris:

myCommand & echo $!

Solusi 2:

Anda dapat menggunakan sh -c dan exec untuk mendapatkan PID perintah bahkan sebelum itu berjalan.

Untuk memulai myCommand , agar PID-nya dicetak sebelum mulai dijalankan, Anda dapat menggunakan:

sh -c 'echo $$; exec myCommand'

Cara kerjanya:

Ini memulai shell baru, mencetak PID dari shell tersebut, dan kemudian menggunakan exec bawaan untuk mengganti shell dengan perintah Anda, memastikannya memiliki PID yang sama. Saat shell Anda menjalankan perintah dengan exec bawaan, shell Anda sebenarnya menjadi perintah itu, daripada perilaku yang lebih umum dari forking salinan baru dari dirinya sendiri, yang memiliki PID tersendiri dan yang kemudian menjadi perintah.

Saya menemukan ini jauh lebih sederhana daripada alternatif yang melibatkan eksekusi asinkron (dengan & ), kontrol tugas, atau menelusuri dengan ps . Pendekatan itu baik-baik saja, tetapi kecuali Anda memiliki alasan khusus untuk menggunakannya--misalnya, mungkin perintah sudah berjalan, dalam hal ini mencari PID-nya atau menggunakan kontrol pekerjaan akan masuk akal--saya sarankan mempertimbangkan cara ini terlebih dahulu. (Dan saya pasti tidak akan mempertimbangkan untuk menulis skrip yang rumit atau program lain untuk mencapai hal ini).

Jawaban ini menyertakan contoh teknik ini.

Bagian dari perintah itu kadang-kadang dapat dihilangkan, tetapi biasanya tidak.

Bahkan jika shell yang Anda gunakan adalah gaya Bourne dan dengan demikian mendukung exec bawaan dengan semantik ini, biasanya Anda tidak boleh mencoba menghindari penggunaan sh -c (atau yang setara) untuk membuat yang baru, terpisah proses shell untuk tujuan ini, karena:

  • Setelah shell menjadi myCommand , tidak ada shell yang menunggu untuk menjalankan perintah selanjutnya. sh -c 'echo $$; exec myCommand; foo tidak akan dapat mencoba menjalankan foo setelah mengganti dirinya sendiri dengan myCommand . Kecuali Anda sedang menulis skrip yang menjalankan ini sebagai perintah terakhirnya, Anda tidak bisa hanya menggunakan echo $$; exec myCommand di shell tempat Anda menjalankan perintah lain.
  • Anda tidak dapat menggunakan subkulit untuk ini. (echo $$; exec myCommand) mungkin secara sintaksis lebih bagus daripada sh -c 'echo $$; exec myCommand' , tetapi saat Anda menjalankan $$ di dalam ( ) , ini memberikan PID dari shell induk, bukan dari subkulit itu sendiri. Tapi itu adalah PID subkulit yang akan menjadi PID dari perintah baru. Beberapa shell menyediakan mekanisme non-portabelnya sendiri untuk menemukan PID subkulit, yang dapat gunakan untuk ini. Secara khusus, di Bash 4, (echo $BASHPID; exec myCommand) berhasil.

Terakhir, perhatikan bahwa beberapa shell akan melakukan pengoptimalan di mana mereka menjalankan perintah seolah-olah dengan exec (yaitu, mereka melupakan forking terlebih dahulu) ketika diketahui bahwa shell tidak perlu melakukan apa pun sesudahnya. Beberapa shell mencoba melakukan ini kapan saja itu adalah perintah terakhir yang dijalankan, sementara yang lain hanya akan melakukannya ketika tidak ada perintah lain sebelum atau sesudah perintah, dan yang lain tidak akan melakukannya sama sekali. Efeknya adalah jika Anda lupa menulis exec dan cukup gunakan sh -c 'echo $$; myCommand' maka itu akan terkadang memberi Anda PID yang tepat di some sistem dengan beberapa kerang. Saya sarankan untuk tidak mengandalkan perilaku seperti itu, dan malah selalu menyertakan exec ketika itu yang Anda butuhkan.

Solusi 3:

Bungkus perintah dalam skrip kecil

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

Solusi 4:

Saya tidak tahu solusi yang lebih sederhana, tetapi tidak menggunakan $! cukup baik? Anda selalu dapat menetapkan nilai ke beberapa variabel lain jika Anda membutuhkannya nanti, seperti yang dikatakan oleh orang lain.

Sebagai catatan tambahan, alih-alih menyalurkan dari ps, Anda dapat menggunakan pgrep atau pidof .

Solusi 5:

gunakan exec dari skrip bash setelah mendaftarkan pid ke file:

contoh:

misalkan Anda memiliki skrip bernama "forever.sh" yang ingin Anda jalankan dengan args p1,p2,p3

kode sumber forever.sh:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"[email protected]\""
    sleep 5
done

buat reaper.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "[email protected]"

jalankan forever.sh melalui reaper.sh:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh tidak lebih dari mencatat satu baris ke syslog setiap 5 detik

Anda sekarang memiliki pid di /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

dan forever.sh berjalan dengan baik. grep syslog:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

Anda dapat melihatnya di tabel proses:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

Linux
  1. Bagaimana Memulai Dengan Server Cloud FreeBSD

  2. Bagaimana cara menemukan ID proses di Ubuntu?

  3. Bagaimana cara mendapatkan jalur proses di Unix / Linux

  1. Bagaimana cara mendapatkan ID proses dari proses latar belakang?

  2. Bagaimana cara mendapatkan ID proses untuk mematikan proses nohup?

  3. Cara mendapatkan PID dari proses anak bercabang di skrip Shell

  1. Proses Boot Linux:Panduan untuk Memulai

  2. Bagaimana cara mendapatkan PID dengan nama proses?

  3. Bagaimana cara mendapatkan pid dari suatu proses dan mengaktifkan kill -9 di skrip Shell?