Apa yang sebenarnya menentukan apakah pekerjaan latar belakang terbunuh ketika shell keluar, atau terbunuh?

12

Pertanyaan ini telah datang cukup sebuah banyak ( benar-benar banyak ), tapi aku menemukan jawaban atas secara umum tidak lengkap. Pertanyaan umum adalah "Mengapa saya tidak terbunuh ketika saya keluar / membunuh ssh?", Dan inilah yang saya temukan. Pertanyaan pertama adalah: Seberapa umum informasi berikut? Berikut ini tampaknya berlaku untuk linux Debian modern, tetapi saya kehilangan beberapa bit; dan apa yang perlu diketahui orang lain?

  1. Semua proses anak, backgrounded atau tidak dari shell dibuka melalui koneksi ssh tewas dengan SIGHUP ketika koneksi ssh ditutup hanya jika itu huponexitopsi disetel: dijalankan shopt huponexituntuk melihat apakah ini benar.

  2. Jika huponexitbenar, maka Anda dapat menggunakan nohupatau disownuntuk memisahkan proses dari shell sehingga tidak terbunuh saat Anda keluar. Atau, jalankan dengan screen.

  3. Jika huponexitsalah, yang merupakan default pada setidaknya beberapa linux hari ini, maka pekerjaan yang di background tidak akan dimatikan pada logout normal.

  4. Tetapi bahkan jika huponexititu salah, maka jika koneksi ssh terbunuh , atau jatuh (berbeda dari logout normal), maka proses latar belakang akan tetap terbunuh. Ini dapat dihindari oleh disownatau nohupseperti pada (2).

  5. Ada beberapa perbedaan antara (a) proses yang proses induknya adalah terminal dan (b) proses yang memiliki stdin, stdout, atau stderr yang terhubung ke terminal . Saya tidak tahu apa yang terjadi pada proses yang (a) dan bukan (b), atau sebaliknya.

Pertanyaan terakhir: Bagaimana saya bisa menghindari perilaku (3)? Dengan kata lain, secara default di proses latar Debian berjalan dengan gembira sendiri setelah logout tetapi tidak setelah koneksi ssh terbunuh. Saya ingin hal yang sama terjadi pada proses terlepas dari apakah koneksi ditutup secara normal atau terbunuh. Atau, apakah ini ide yang buruk?

Sunting: Cara lain yang penting untuk menjaga agar pekerjaan tidak terbunuh, yang berfungsi (?) Adalah menjalankannya melalui layar . Tapi, pertanyaannya lebih pada pemahaman ketika hal-hal terbunuh dan ketika tidak: kadang-kadang orang ingin pekerjaan dibunuh saat logout, misalnya.

Utas lainnya: - Klarifikasi sinyal (sighup), pekerjaan, dan terminal pengontrol - /server/117152/do-background-processes-get-a-sighup-when-logging-off - Lanjutkan SSH tugas / pekerjaan latar belakang saat menutup SSH - Apakah pekerjaan yang dimasukkan di latar belakang terus berjalan setelah sesi SSH ditutup? - Mencegah proses latar belakang yang sudah berjalan dihentikan setelah menutup klien SSH - Bagaimana saya bisa memulai proses melalui SSH sehingga akan terus berjalan setelah saya lepaskan? - Tidak dapat menjaga pekerjaan jarak jauh berjalan di OS X - Tutup koneksi SSH

petrelharp
sumber

Jawaban:

1

Suatu proses tidak "terbunuh dengan SIGHUP" - setidaknya, tidak dalam arti kata yang sebenarnya. Sebaliknya, ketika koneksi terputus, proses kontrol terminal (dalam hal ini, Bash) dikirim sinyal hang-up *, yang biasanya disingkat "sinyal HUP", atau hanya SIGHUP.

Sekarang, ketika suatu proses menerima sinyal, ia dapat menanganinya dengan cara apa pun yang diinginkan **. Default untuk sebagian besar sinyal (termasuk HUP) adalah untuk segera keluar. Namun, program ini bebas untuk mengabaikan sinyal, atau bahkan menjalankan semacam fungsi pengendali sinyal.

Bash memilih opsi terakhir. Handler sinyal HUP-nya memeriksa untuk melihat apakah opsi "huponexit" benar, dan jika demikian, mengirimkan SIGHUP ke masing-masing proses anaknya. Hanya setelah selesai dengan itu Bash keluar.

Demikian juga, setiap proses anak bebas untuk melakukan apa pun yang diinginkannya ketika menerima sinyal: biarkan diset ke default (yaitu segera mati), abaikan saja, atau jalankan pengendali sinyal.

Nohup hanya mengubah tindakan default untuk proses anak untuk "diabaikan". Namun begitu proses anak berjalan, bebas mengubah responsnya sendiri terhadap sinyal.

Ini, saya pikir, itulah sebabnya beberapa program mati walaupun Anda menjalankannya dengan nohup:

  1. Nohup menetapkan tindakan default untuk "diabaikan".
  2. Program perlu melakukan semacam pembersihan saat keluar, sehingga menginstal pawang SIGHUP, secara tidak sengaja menimpa bendera "abaikan".
  3. Ketika SIGHUP tiba, pawang berjalan, membersihkan file data program (atau apa pun yang perlu dilakukan) dan keluar dari program.
  4. Pengguna tidak tahu atau tidak peduli dengan handler atau pembersihan, dan hanya melihat bahwa program keluar meskipun tidak ada.

Di sinilah "disown" masuk. Proses yang telah ditolak oleh Bash tidak pernah mengirim sinyal HUP, terlepas dari opsi huponexit. Jadi, bahkan jika program mengatur pengendali sinyal sendiri, sinyal tidak pernah benar-benar dikirim, sehingga pengendali tidak pernah berjalan. Perhatikan, bagaimanapun, bahwa jika program mencoba untuk menampilkan beberapa teks ke pengguna yang keluar, itu akan menyebabkan kesalahan I / O, yang dapat menyebabkan program untuk tetap keluar.

* Dan, ya, sebelum Anda bertanya, terminologi "hang-up" tersisa dari hari-hari mainframe dialup UNIX.

** Sebagian besar sinyal. SIGKILL, misalnya, selalu menyebabkan program untuk segera berakhir, titik.

HiddenWindshield
sumber
2

Poin 1-4 benar. Saya tidak tahu apa-apa tentang poin 5. Adapun poin terakhir Anda, aplikasi yang bagus, layar , akan memungkinkan Anda untuk membiarkan semua proses berjalan sampai akhir, terlepas dari bagaimana Anda memutuskan koneksi Anda. Layar dalam repo.

Uraian pria layar tidak mudah dibaca, tetapi, antara lain, menyatakan:

Ketika layar dipanggil, itu menciptakan satu jendela dengan shell di dalamnya (atau perintah yang ditentukan) dan kemudian keluar dari jalan Anda sehingga Anda dapat menggunakan program seperti biasa. Kemudian, kapan saja, Anda dapat membuat jendela baru (layar penuh) dengan program lain di dalamnya (termasuk lebih banyak cangkang), mematikan jendela yang ada, melihat daftar jendela, menghidupkan dan mematikan keluaran log, dan salin dan tempel teks antara windows, melihat riwayat scrollback, beralih antar windows dengan cara apa pun yang Anda inginkan, dll. Semua windows menjalankan program mereka sepenuhnya satu sama lain. Program terus berjalan ketika jendela mereka saat ini tidak terlihat dan bahkan ketika seluruh sesi layar terlepas dari terminal pengguna. Ketika sebuah program berakhir, layar (per default) membunuh jendela yang berisi itu. Jika jendela ini berada di latar depan, layar beralih ke jendela sebelumnya; jika tidak ada yang tersisa, layar keluar.

Saya telah menyoroti bagian paling penting: Anda dapat melepaskan jendela dengan perintah Ctrl + a + d, dan kemudian Anda dapat membunuh / logout sesi Anda, dan jendela yang sekarang terlepas akan terus hidup, dengan program-program di dalamnya masih berjalan. Ketika Anda terhubung kembali, misalnya dengan memulai sesi ssh baru, layar perintah -r akan melanjutkan sesi layar yang telah terlepas sebelumnya, dengan semua output ke standard error / output terlihat jelas.

MariusMatutiae
sumber