Apakah terputus dari sesi SSH membunuh program Anda?
88
Jadi, katakan saya terputus dari sesi SSH setelah saya mulai rsyncatau cpperintah lain yang bisa berjalan lama. Apakah perintah itu terus berjalan sampai selesai setelah saya terputus atau hanya terbunuh?
Saya hanya ingin menambahkan apa yang telah dikatakan di atas bahwa, jika Anda menemukan diri Anda dalam situasi ketika Anda perlu memasukkan proses yang sudah berjalan screen, coba reptyr .
Bung sedih
Ini akan mematikan program Anda. Sangat menjengkelkan jika Anda memperbarui versi OS dari katakanlah Ubuntu 16.04 ke 17.10 melalui SSH
kurdtpage
Jawaban:
118
Edit untuk 2016:
T&J ini mendahului bencana systemd v230 . Pada systemd v230, default baru adalah untuk membunuh semua anak dari sesi login penghentian, terlepas dari apa tindakan pencegahan yang secara historis sah diambil untuk mencegah hal ini. Perilaku dapat diubah dengan menetapkan KillUserProcesses=nodalam /etc/systemd/logind.conf, atau dielakkan menggunakan mekanisme systemd-spesifik untuk memulai daemon di userspace. Mekanisme-mekanisme itu berada di luar ruang lingkup pertanyaan ini.
Teks di bawah ini menjelaskan bagaimana hal-hal secara tradisional bekerja di ruang desain UNIX lebih lama dari yang ada Linux.
Mereka akan terbunuh, tetapi tidak harus segera. Itu tergantung pada berapa lama untuk daemon SSH untuk memutuskan bahwa koneksi Anda sudah mati. Berikut ini adalah penjelasan yang lebih panjang yang akan membantu Anda memahami cara kerjanya.
Ketika Anda login, daemon SSH mengalokasikan pseudo-terminal untuk Anda dan melampirkannya pada shell login yang dikonfigurasi pengguna Anda. Ini disebut terminal pengendali. Setiap program yang Anda mulai secara normal pada titik itu, tidak peduli berapa banyak lapisan dalam kerang, pada akhirnya akan melacak leluhurnya kembali ke kerang itu. Anda dapat mengamati ini dengan pstreeperintah.
Ketika proses daemon SSH yang terkait dengan koneksi Anda memutuskan bahwa koneksi Anda sudah mati, ia mengirimkan sinyal hangup ( SIGHUP) ke shell login. Ini memberi tahu shell yang telah Anda hilangkan dan harusnya mulai dibersihkan setelahnya. Apa yang terjadi pada titik ini adalah spesifik shell (cari halaman dokumentasinya untuk "HUP"), tetapi sebagian besar akan mulai mengirim SIGHUPke menjalankan pekerjaan yang terkait dengannya sebelum berakhir. Masing-masing proses tersebut, pada gilirannya, akan melakukan apa pun yang dikonfigurasikan untuk dilakukan setelah menerima sinyal itu. Biasanya itu berarti mengakhiri. Jika pekerjaan-pekerjaan itu memiliki pekerjaan mereka sendiri, sinyalnya akan sering diteruskan juga.
Proses yang bertahan dari hangup terminal pengendali adalah proses yang memisahkan diri dari terminal (proses daemon yang Anda mulai di dalamnya), atau proses yang dipanggil dengan nohupperintah yang diawali . (yaitu "jangan menutup ini") Daemon menafsirkan sinyal HUP berbeda; karena mereka tidak memiliki terminal pengendali dan tidak secara otomatis menerima sinyal HUP, itu sebaliknya digunakan kembali sebagai permintaan manual dari administrator untuk memuat ulang konfigurasi. Ironisnya, ini berarti bahwa sebagian besar admin tidak mempelajari "hangup" penggunaan sinyal ini untuk non-daemon sampai jauh, jauh di kemudian hari. Itu sebabnya Anda membaca ini!
Terminal multiplexer adalah cara umum untuk menjaga lingkungan shell Anda tetap utuh di antara pemutusan. Mereka memungkinkan Anda untuk melepaskan diri dari proses shell Anda dengan cara yang dapat Anda pasang kembali ke mereka nanti, terlepas dari apakah pemutusan itu kebetulan atau sengaja. tmuxdan screenyang lebih populer; sintaks untuk menggunakannya berada di luar cakupan pertanyaan Anda, tetapi mereka layak untuk dilihat.
Diminta agar saya menguraikan berapa lama waktu yang dibutuhkan daemon SSH untuk memutuskan bahwa koneksi Anda sudah mati. Ini adalah perilaku yang spesifik untuk setiap implementasi daemon SSH, tetapi Anda dapat mengandalkan semuanya untuk diakhiri ketika kedua sisi me-reset koneksi TCP. Ini akan terjadi dengan cepat jika server mencoba menulis ke soket dan paket TCP tidak diakui, atau lambat jika tidak ada yang mencoba menulis ke PTY.
Dalam konteks khusus ini, faktor-faktor yang paling mungkin memicu penulisan adalah:
Sebuah proses (biasanya yang ada di latar depan) berusaha menulis ke PTY di sisi server. (server-> klien)
Pengguna mencoba menulis ke PTY di sisi klien. (client-> server)
Keepalives dalam bentuk apa pun. Ini biasanya tidak diaktifkan secara default, baik oleh klien atau server, dan biasanya ada dua rasa: tingkat aplikasi dan berbasis TCP (yaitu SO_KEEPALIVE). Jumlah keepalives baik ke server atau klien jarang mengirim paket ke sisi lain, bahkan ketika tidak ada yang dinyatakan memiliki alasan untuk menulis ke soket. Meskipun ini biasanya dimaksudkan untuk meng-rok firewall yang memutuskan koneksi terlalu cepat, ia memiliki efek samping tambahan yang menyebabkan pengirim mengetahui ketika pihak lain tidak merespons dengan lebih cepat.
Aturan biasa untuk sesi TCP berlaku di sini: jika ada gangguan dalam konektivitas antara klien dan server, tetapi tidak ada pihak yang mencoba mengirim paket selama masalah, koneksi akan bertahan asalkan kedua belah pihak responsif setelah itu dan menerima TCP yang diharapkan nomor urut.
Jika satu pihak telah memutuskan bahwa soket sudah mati, efeknya biasanya langsung: proses sshd akan mengirim HUPdan mengakhiri sendiri (seperti dijelaskan sebelumnya), atau klien akan memberi tahu pengguna tentang masalah yang terdeteksi. Perlu dicatat bahwa hanya karena satu pihak berpikir yang lain mati tidak berarti bahwa pihak lain telah diberitahu tentang ini. Sisi yatim dari koneksi biasanya akan tetap terbuka sampai ia mencoba untuk menulis dan keluar, atau menerima reset TCP dari sisi lain. (jika konektivitas tersedia pada saat itu) Pembersihan yang dijelaskan dalam jawaban ini hanya terjadi setelah server memperhatikan.
Saya juga menambahkan perintah 'dtach' ke daftar itu - ini adalah kebalikan dari layar / tmux karena memungkinkan Anda melampirkan beberapa terminal ke satu sesi, dan juga bagus untuk memperpanjang sesi, meskipun tidak memberikan segala cara untuk memutar ulang sejarah baru-baru ini.
penjelasan yang sangat baik. Saya sudah merasakan lebih banyak linuxey!
fregas
3
Selain itu, meskipun secara teknis bukan bagian dari jawaban Anda, berikut ini adalah hal-hal sepele yang menarik: Anda dapat menggunakan kill -HUPsebagai root untuk memaksa terminal seseorang untuk menutup telepon. Anda seharusnya tidak melakukan ini tanpa alasan yang kuat. Saya mendapatkan sebagian besar jarak tempuh saya keluar dari itu ketika pengguna membiarkan shell berjalan selama pemeliharaan dan saya perlu meng-unmount sistem file yang shell mereka tetap terbuka. Jika pengguna terhubung tetapi tidak aktif, kirim sinyal ke proses sshd mereka. Kalau tidak, jika itu berjalan di dalam terminal multiplexer, kirimkan ke shell yang ingin Anda hentikan. Hanya tutup cangkang agar Anda tidak bekerja!
Andrew B
@AndrewB, bisa tolong jelaskan bagaimana "proses daemon SSH ... memutuskan bahwa koneksi Anda sudah mati"? Dan bagaimana saya bisa tahu jika daemon SSH berpikir / tahu bahwa koneksi (yang) mati atau tidak?
Xiao Peng - ZenUML.com
22
Seperti yang disebutkan oleh orang lain, setelah Anda memutuskan sambungan dari ssh apa pun yang berjalan di dalamnya hilang.
Seperti @Michael Hampton dan yang lainnya telah menyebutkan Anda dapat menggunakan alat seperti tmuxatau screenuntuk memutuskan / menghubungkan kembali ke terminal tanpa kehilangan konten mereka (yaitu proses anak).
Selain itu Anda dapat menempatkan proses ke latar belakang menggunakan ampersand &dan kemudian menggunakan perintah disownuntuk memisahkan mereka dengan shell saat ini.
# start a command
% sleep 5000 &
[1] 3820
# check it
% jobs
[1]+ Running sleep 5000 &
# disown everything
% disown -a
# check it again (gone from shell)
% jobs
%
# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml 3820 23791 0 00:16 pts/1 00:00:00 sleep 5000
%
Tidak, program apa pun yang masih melekat pada terminal, dan tidak diletakkan di latar belakang dengan sesuatu seperti nohup, akan dibunuh.
Inilah sebabnya mengapa ada solusi terminal virtual seperti tmuxdan yang lebih lama screenyang membuat sesi yang terus berjalan bahkan jika Anda terputus, dan yang dapat Anda pasang kembali nanti.
screen
, coba reptyr .Jawaban:
Edit untuk 2016:
T&J ini mendahului bencana systemd v230 . Pada systemd v230, default baru adalah untuk membunuh semua anak dari sesi login penghentian, terlepas dari apa tindakan pencegahan yang secara historis sah diambil untuk mencegah hal ini. Perilaku dapat diubah dengan menetapkan
KillUserProcesses=no
dalam/etc/systemd/logind.conf
, atau dielakkan menggunakan mekanisme systemd-spesifik untuk memulai daemon di userspace. Mekanisme-mekanisme itu berada di luar ruang lingkup pertanyaan ini.Teks di bawah ini menjelaskan bagaimana hal-hal secara tradisional bekerja di ruang desain UNIX lebih lama dari yang ada Linux.
Mereka akan terbunuh, tetapi tidak harus segera. Itu tergantung pada berapa lama untuk daemon SSH untuk memutuskan bahwa koneksi Anda sudah mati. Berikut ini adalah penjelasan yang lebih panjang yang akan membantu Anda memahami cara kerjanya.
Ketika Anda login, daemon SSH mengalokasikan pseudo-terminal untuk Anda dan melampirkannya pada shell login yang dikonfigurasi pengguna Anda. Ini disebut terminal pengendali. Setiap program yang Anda mulai secara normal pada titik itu, tidak peduli berapa banyak lapisan dalam kerang, pada akhirnya akan melacak leluhurnya kembali ke kerang itu. Anda dapat mengamati ini dengan
pstree
perintah.Ketika proses daemon SSH yang terkait dengan koneksi Anda memutuskan bahwa koneksi Anda sudah mati, ia mengirimkan sinyal hangup (
SIGHUP
) ke shell login. Ini memberi tahu shell yang telah Anda hilangkan dan harusnya mulai dibersihkan setelahnya. Apa yang terjadi pada titik ini adalah spesifik shell (cari halaman dokumentasinya untuk "HUP"), tetapi sebagian besar akan mulai mengirimSIGHUP
ke menjalankan pekerjaan yang terkait dengannya sebelum berakhir. Masing-masing proses tersebut, pada gilirannya, akan melakukan apa pun yang dikonfigurasikan untuk dilakukan setelah menerima sinyal itu. Biasanya itu berarti mengakhiri. Jika pekerjaan-pekerjaan itu memiliki pekerjaan mereka sendiri, sinyalnya akan sering diteruskan juga.Proses yang bertahan dari hangup terminal pengendali adalah proses yang memisahkan diri dari terminal (proses daemon yang Anda mulai di dalamnya), atau proses yang dipanggil dengan
nohup
perintah yang diawali . (yaitu "jangan menutup ini") Daemon menafsirkan sinyal HUP berbeda; karena mereka tidak memiliki terminal pengendali dan tidak secara otomatis menerima sinyal HUP, itu sebaliknya digunakan kembali sebagai permintaan manual dari administrator untuk memuat ulang konfigurasi. Ironisnya, ini berarti bahwa sebagian besar admin tidak mempelajari "hangup" penggunaan sinyal ini untuk non-daemon sampai jauh, jauh di kemudian hari. Itu sebabnya Anda membaca ini!Terminal multiplexer adalah cara umum untuk menjaga lingkungan shell Anda tetap utuh di antara pemutusan. Mereka memungkinkan Anda untuk melepaskan diri dari proses shell Anda dengan cara yang dapat Anda pasang kembali ke mereka nanti, terlepas dari apakah pemutusan itu kebetulan atau sengaja.
tmux
danscreen
yang lebih populer; sintaks untuk menggunakannya berada di luar cakupan pertanyaan Anda, tetapi mereka layak untuk dilihat.Diminta agar saya menguraikan berapa lama waktu yang dibutuhkan daemon SSH untuk memutuskan bahwa koneksi Anda sudah mati. Ini adalah perilaku yang spesifik untuk setiap implementasi daemon SSH, tetapi Anda dapat mengandalkan semuanya untuk diakhiri ketika kedua sisi me-reset koneksi TCP. Ini akan terjadi dengan cepat jika server mencoba menulis ke soket dan paket TCP tidak diakui, atau lambat jika tidak ada yang mencoba menulis ke PTY.
Dalam konteks khusus ini, faktor-faktor yang paling mungkin memicu penulisan adalah:
SO_KEEPALIVE
). Jumlah keepalives baik ke server atau klien jarang mengirim paket ke sisi lain, bahkan ketika tidak ada yang dinyatakan memiliki alasan untuk menulis ke soket. Meskipun ini biasanya dimaksudkan untuk meng-rok firewall yang memutuskan koneksi terlalu cepat, ia memiliki efek samping tambahan yang menyebabkan pengirim mengetahui ketika pihak lain tidak merespons dengan lebih cepat.Aturan biasa untuk sesi TCP berlaku di sini: jika ada gangguan dalam konektivitas antara klien dan server, tetapi tidak ada pihak yang mencoba mengirim paket selama masalah, koneksi akan bertahan asalkan kedua belah pihak responsif setelah itu dan menerima TCP yang diharapkan nomor urut.
Jika satu pihak telah memutuskan bahwa soket sudah mati, efeknya biasanya langsung: proses sshd akan mengirim
HUP
dan mengakhiri sendiri (seperti dijelaskan sebelumnya), atau klien akan memberi tahu pengguna tentang masalah yang terdeteksi. Perlu dicatat bahwa hanya karena satu pihak berpikir yang lain mati tidak berarti bahwa pihak lain telah diberitahu tentang ini. Sisi yatim dari koneksi biasanya akan tetap terbuka sampai ia mencoba untuk menulis dan keluar, atau menerima reset TCP dari sisi lain. (jika konektivitas tersedia pada saat itu) Pembersihan yang dijelaskan dalam jawaban ini hanya terjadi setelah server memperhatikan.sumber
dtach
url ada di sini: dtach.sourceforge.netkill -HUP
sebagai root untuk memaksa terminal seseorang untuk menutup telepon. Anda seharusnya tidak melakukan ini tanpa alasan yang kuat. Saya mendapatkan sebagian besar jarak tempuh saya keluar dari itu ketika pengguna membiarkan shell berjalan selama pemeliharaan dan saya perlu meng-unmount sistem file yang shell mereka tetap terbuka. Jika pengguna terhubung tetapi tidak aktif, kirim sinyal ke proses sshd mereka. Kalau tidak, jika itu berjalan di dalam terminal multiplexer, kirimkan ke shell yang ingin Anda hentikan. Hanya tutup cangkang agar Anda tidak bekerja!Seperti yang disebutkan oleh orang lain, setelah Anda memutuskan sambungan dari ssh apa pun yang berjalan di dalamnya hilang.
Seperti @Michael Hampton dan yang lainnya telah menyebutkan Anda dapat menggunakan alat seperti
tmux
atauscreen
untuk memutuskan / menghubungkan kembali ke terminal tanpa kehilangan konten mereka (yaitu proses anak).Selain itu Anda dapat menempatkan proses ke latar belakang menggunakan ampersand
&
dan kemudian menggunakan perintahdisown
untuk memisahkan mereka dengan shell saat ini.sumber
disown
proses ed?Tidak, program apa pun yang masih melekat pada terminal, dan tidak diletakkan di latar belakang dengan sesuatu seperti
nohup
, akan dibunuh.Inilah sebabnya mengapa ada solusi terminal virtual seperti
tmux
dan yang lebih lamascreen
yang membuat sesi yang terus berjalan bahkan jika Anda terputus, dan yang dapat Anda pasang kembali nanti.sumber