Mengapa proses saya masih berjalan setelah saya keluar?

10

Setelah masuk ssh, saya mengetik perintah ini di bash:

sleep 50000000000000 &

Lalu aku kill -9yang sleepproses induk proses (yaitu, bash). Kemudian jendela terminal terputus secara bersamaan.

Ketika saya masuk lagi, saya menemukan bahwa sleepprosesnya masih hidup.

Pertanyaan : Mengapa sleepproses bisa bertahan ketika saya logout dan terminal ditutup? Dalam pikiran saya, segala sesuatu kecuali daemon dan nohupprogram akan terbunuh saat logout. Jika sleepdapat bertahan dengan cara ini, apakah ini berarti saya dapat menggunakan metode ini alih-alih nohupperintah?

kucing jantan
sumber
3
&akan memotong proses ke latar belakang (seperti daemon) dan tetap berjalan walaupun Anda sudah keluar.
Aizuddin Zali

Jawaban:

6

Tl; dr:

Mengapa sleepproses bisa bertahan ketika saya logout dan terminal ditutup? Dalam pikiran saya, segala sesuatu kecuali daemon dan nohupprogram akan terbunuh saat logout Jika sleepdapat bertahan dengan cara ini, apakah ini berarti saya dapat menggunakan metode ini alih-alih nohupperintah?

Kecuali jika bashinstance yang dimunculkan oleh sshmemiliki huponexitset opsi, tidak ada proses akan dihentikan dengan cara apa pun pada saat keluar / log out, dan ketika huponexitopsi ditetapkan, menggunakan kill -9pada shell bukanlah alternatif yang baik untuk digunakan nohuppada proses anak-anak shell; nohuppada proses cangkang anak masih akan melindungi mereka dari SIGHUP yang tidak datang dari cangkang, dan bahkan ketika itu tidak penting nohupmasih lebih disukai karena memungkinkan cangkang diakhiri dengan anggun.


Di bashsana ada opsi yang disebut huponexit, yang jika diatur akan membuat bashSIGHUP anak-anaknya saat keluar / keluar;

Dalam instance non-login interaktif bash, seperti dalam bashinstance yang dibuat oleh gnome-terminal, opsi ini diabaikan; apakah huponexitdiatur atau tidak disetel, bashanak-anak tidak akan pernah DIJELASKAN bashsaat keluar;

Dalam instance login interaktif bash, seperti dalam bashinstance yang dibuat oleh ssh, opsi ini tidak diabaikan (namun tidak disetel secara default); jika huponexitdiatur, bashanak-anak akan DIJELASKAN bashsaat keluar / keluar; jika huponexittidak disetel, bashanak-anak tidak akan DIJELASKAN bashsaat keluar / keluar;

Jadi secara umum keluar / keluar dari bashinstance login interaktif , kecuali jika huponexitopsi disetel, tidak akan membuat shell SIGHUP anak-anaknya, dan keluar / keluar dari bashinstance non-login interaktif tidak akan membuat shell SIGHUP anak-anaknya bagaimanapun;

Namun, ini tidak relevan dalam kasus ini: menggunakan kill -9 sleepakan tetap bertahan, karena membunuh proses induknya ( bash) tidak akan meninggalkan kesempatan bagi yang terakhir untuk melakukan apa pun pada yang pertama (yaitu, misalnya, jika bashinstance saat ini adalah bashinstance login dan huponexitopsinya diset, untuk SIGHUP itu).

Menambah ini, tidak seperti sinyal lain (seperti sinyal SIGHUP dikirim ke bash), sinyal SIGKILL tidak pernah disebarkan ke proses anak proses, karenanya sleepbahkan tidak dibunuh;

nohupmemulai proses yang kebal terhadap sinyal SIGHUP, yang merupakan sesuatu yang berbeda; itu akan mencegah proses menggantung pada penerimaan sinyal SIGHUP, yang dalam hal ini dapat diterima oleh bashinstance login interaktif jika huponexitopsi telah diatur dan shell keluar; jadi secara teknis menggunakan nohupuntuk memulai proses dalam bashinstance login interaktif dengan huponexitopsi tidak disetel akan mencegah proses menggantung pada penerimaan sinyal SIGHUP, tetapi keluar / keluar dari shell tidak akan SIGHUP terlepas;

Namun, secara umum, ketika nohupdiperlukan untuk mencegah sinyal SIGHUP yang berasal dari shell induk, tidak ada alasan untuk lebih suka kill -9metode induk pada metode nohupon the child; sebaliknya, seharusnya sebaliknya.

Membunuh orang tua menggunakan kill -9metode ini tidak memberikan kesempatan bagi orang tua untuk keluar dengan anggun, sementara memulai anak menggunakan nohupmetode ini memungkinkan orang tua untuk dihentikan oleh sinyal lain, seperti SIGHUP (untuk membuat contoh yang masuk akal dalam konteks seorang anak mulai menggunakan nohup), yang memungkinkan untuk keluar dengan anggun.

kos
sumber
Dengan kata lain, jika saya memiliki skrip yang ditempatkan di latar belakang, itu akan tetap berjalan bahkan jika saya membunuh proses induk, misalnya shell saya kan? apa yang akan menjadi cara untuk membunuh skrip itu?
Sergiy Kolodyazhnyy
@Serg Jika Anda memiliki PID, cukup bunuh PID; jika Anda tidak menyimpan PID tetapi Anda dapat mengidentifikasi proses dengan namanya, ps -e | grep processharus mendaftarkan proses bersama dengan PID (atau lebih baik hanya pgrep -x processjika Anda yakin akan mencocokkan proses tunggal itu dan bukan hal-hal yang tidak memiliki tenda); masalahnya adalah bahwa ketika Anda membunuh proses dengan kill -9anak-anaknya dimiliki upstart, maka PPID asli mereka hilang dan PPID mereka berubah menjadi PID pemula, membuat mereka tidak dapat dikenali (AFAIK) tetapi untuk nama mereka atau PID
kos
@kos Dalam kondisi apa nohupakan gagal untuk mencegah proses menutup setelah menerima sinyal SIGHUP dari proses induk? Saya mencoba menjalankan proses di latar belakang (di terminal shell SST Putty) oleh nohup <command> <arg> &. Ketika saya keluar dengan mengklik Xtombol Putty , proses latar belakang akan segera berakhir. Ketika saya keluar dengan mengetikkan exitterminal shell Putty SSH, proses akan terus berjalan di latar belakang.
userpal
3

bashsecara default tidak mengirimkan sinyal HUP ke proses anak saat keluar . Lebih detail (terima kasih @kos), tidak pernah melakukannya untuk kerang non-login .

Anda dapat mengonfigurasi bash untuk melakukannya untuk shell login jika menetapkan opsi huponexit. Di terminal, lakukan:

[romano:~] % bash -l

(ini memulai shell "login" baru)

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

Sekarang periksa sleepprosesnya:

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

... tidak berjalan: telah menerima sinyal HUP dan keluar seperti yang diminta.

Rmano
sumber
@kos --- ya, Anda benar tapi ... jadi mengapa jika saya sleep 1000 & ; exityang sleepbertahan? Perhatikan bahwa jika saya kill -HUPyang sleepproses itu akan keluar. Dan bahkan jika huponexitdiatur, sleepbertahan. Bingung ... (Saya akan mencoba memahami dengan lebih baik dan memodifikasi asnwer, kalau tidak saya akan menghapusnya).
Rmano
2

Jika sleepdapat bertahan dengan cara ini, apakah itu berarti saya dapat menggunakan metode ini alih-alih nohupperintah?

kill -9benar-benar bukan cara yang seharusnya. Ini seperti menembak dengan pistol di TV untuk mematikannya. Selain komponen komedi tidak ada keuntungan. Proses tidak dapat menangkap atau mengabaikan SIGKILL. Jika Anda tidak memberikan proses kesempatan untuk menyelesaikan apa yang dilakukan dan dibersihkan, proses itu mungkin meninggalkan file yang rusak (atau keadaan lainnya) dan tidak akan dapat memulai lagi. kill -9adalah harapan terakhir, ketika tidak ada lagi yang berhasil.


Mengapa proses tidur bisa bertahan ketika saya logout dan terminal ditutup. Dalam pikiranku, semua kecuali program daemon dan nohup akan terbunuh saat keluar.

Apa yang terjadi dalam kasus Anda:

Proses induk sleepadalah bashshell yang sedang berjalan . Ketika Anda kill -9bash itu, proses bash tidak memiliki kesempatan untuk mengirim SIGHUPke salah satu proses anaknya, karena SIGKILL(yang dikirim oleh kill -9) tidak dapat ditangkap oleh proses. Proses tidur terus berjalan. tidur sekarang menjadi proses anak yatim .

Proses init (PID 1) melakukan mekanisme yang disebut reparenting. Itu berarti bahwa proses init sekarang menjadi induk dari proses yatim itu. init adalah pengecualian, proses dapat menjadi anak itu karena mengumpulkan proses yang kehilangan proses induk aslinya. Btw: A daemon (seperti sshd) melakukan itu ketika "pergi di latar belakang".

Jika itu tidak terjadi, proses yatim piatu nantinya (setelah selesai) menjadi proses zombie. Inilah yang terjadi ketika waitpid()tidak dipanggil (tanggung jawab proses induk yang tidak dapat dipenuhi ketika ketika proses itu terbunuh). init memanggil waitpid()dalam intervensi khusus untuk menghindari anak-anak zombie.

kekacauan
sumber
Proses ini bertahan bahkan dengan sinyal sopan seperti TERMatauHUP
heemayl
@heemayl HUP tergantung pada kerang config: huponext. Dan JANGKA akan menunggu sampai tidur selesai. Dalam kasus perintah tidur OP, itu akan menjadi ribuan tahun =)
kekacauan
1

The &dimulai proses di latar belakang. Jika Anda mengetik ps -ef, Anda akan melihat bahwa ID proses induk (PPID) dari tidur Anda adalah bash Anda. Kemudian logout dan login lagi. Proses akan tetap berjalan setelah Anda keluar. Setelah Anda masuk untuk kedua kalinya Anda menjalankan ps -eflagi. Anda akan melihat bahwa sekarang orang tua dari proses tidur Anda akan diproses dengan id "1". Itu init, induk dari semua proses.

tak seorangpun
sumber
0

Penggunaan &akan menyebabkan program berjalan sebagai latar belakang. Untuk melihat program di latar belakang gunakan bgperintah, dan untuk membuatnya berjalan sebagai latar depan lagi, jalankan fg.

Ya, ada banyak cara untuk menjaga program tetap berjalan meskipun terminal utama sudah keluar.

Aizuddin Zali
sumber
Terima kasih. halaman manual bash agak membingungkan. Dikatakan bahwa: "Sebelum keluar, shell interaktif mengirim ulang SIGHUP ke semua pekerjaan, berlari atau berhenti." TAPI sebenarnya, shell hanya mengirim SIGHUP ke pekerjaan forground . proses latar belakang tidak memiliki kesempatan untuk menerima sinyal SIGHUP (kecuali jika mengubah opsi shell 'huponexit')
tom_cat
@kos mungkin Anda benar. Saya menarik kesimpulan di atas dari posting ini: stackoverflow.com/questions/4298741/… sekarang, saya membuat diri saya lebih bingung.
tom_cat
@tom_cat Kembali ke ini lagi, pikirkan dua kali: tidak ada kasus di mana shell dapat keluar dengan proses foreground berjalan, bisa SIGHUP atau sesuatu, tapi itu tidak keluar . Jadi itu benar, itu hanya berlaku untuk proses latar belakang, karena sebaliknya tidak masuk akal. Namun dari penelitian lebih lanjut, pikiran juga yang huponexithanya bekerja pada shell login seperti shell yang diperoleh melalui ssh(dan tidak, katakanlah, dalam shell yang diperoleh via gnome-terminal)
kos