Apakah program berjalan dari sesi ssh tergantung pada koneksi?

29

Apakah program yang dijalankan dari sesi ssh tergantung pada koneksi ke klien? Misalnya saat koneksi benar-benar lambat. Jadi apakah itu aktif menunggu sampai barang dicetak di layar?

Dan jika itu tergantung pada koneksi, apakah itu juga terjadi dengan layar atau byobu misalnya? Karena dengan ini, program-program tetap berjalan bahkan setelah terputus dari tuan rumah.


Catatan: Saya hanya menemukan pertanyaan terkait ini:

agold
sumber
1
Perhatikan bahwa jika koneksi Anda terputus, program akan terus berjalan hingga batas waktu sesi (kecuali jika macet dalam operasi cetak), tetapi jika sesi Anda berakhir, program akan dihentikan dengan anggun.
Sebb

Jawaban:

26

Output dari program buffered, jadi jika koneksi lambat program akan terhenti jika buffer terisi.

Jika Anda menggunakannya screen, ia juga memiliki buffer yang digunakan untuk mencoba dan menampilkan sesi yang terhubung. Tetapi program yang terhubung dalam sesi layar tidak akan dihentikan jika screentidak dapat memperbarui terminal jarak jauh dengan cukup cepat. Sama seperti ketika koneksi terputus, program terus mengisi screensbuffer hingga meluap (mendorong keluar informasi tertua). Apa yang Anda lihat masuk (dan dapat menggulir kembali ke) tergantung pada apa (masih) di buffer itu. screensecara efektif memisahkan program Anda dari terminal Anda (dan koneksi SSH Anda yang lambat).

Anthon
sumber
9

Koneksi SSH dapat mati sebelum waktunya jika koneksi TCP yang mendasarinya menerima paket dengan flag RST . Itu bisa terjadi jika satu sisi mengirim paket (yang mungkin merupakan probe keepalive SSH periodik) tetapi tidak menerima pengakuan TCP dalam jumlah waktu yang wajar, atau jika router memutuskan bahwa koneksi terlalu lama menganggur, atau jika ISP hanya jahat.

Dalam model terminal Unix, ketika koneksi terminal putus, driver terminal mengirimkan sinyal HUP ke shell, yang pemutusannya juga menyebabkan SIGHUP dikirim ke proses yang berjalan di shell.

Dari FAQ Programmer Unix , item 1.15:

SIGHUPadalah sinyal yang berarti, dengan konvensi, "jalur terminal terputus". Ini tidak ada hubungannya dengan proses induk, dan biasanya dihasilkan oleh driver tty (dan dikirimkan ke grup proses latar depan).

Namun, sebagai bagian dari sistem manajemen sesi, ada tepat dua kasus di mana SIGHUPdikirim pada kematian suatu proses:

  • Ketika proses yang mati adalah pemimpin sesi dari sesi yang dilampirkan ke perangkat terminal, SIGHUPdikirim ke semua proses dalam kelompok proses latar depan perangkat terminal itu.

  • Ketika kematian suatu proses menyebabkan kelompok proses menjadi yatim piatu, dan satu atau lebih proses dalam kelompok yatim dihentikan , kemudian SIGHUPdan SIGCONTdikirim ke semua anggota kelompok yatim. (Grup proses yatim piatu adalah grup yang tidak memiliki proses dalam grup yang memiliki induk yang merupakan bagian dari sesi yang sama, tetapi bukan grup proses yang sama.)

The Sinyal standar handler untuk SIGHUP adalah untuk menghentikan proses:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Dimungkinkan untuk menghindari penghentian proses.

  • Anda dapat memasukkan penangan sinyal yang mengabaikan SIGHUP. Untuk melakukannya sebagai pengguna, bungkus perintah nohup. Sebagai contoh:

    nohup make all &
    
  • Anda dapat memberi tahu shell untuk memisahkan proses anak darinya. Misalnya, Bash memiliki disownperintah bawaan:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Kemudian, SIGHUP tidak akan disebarkan ke anak (yang bukan lagi anak-anak).

  • Beberapa program, terutama daemon , akan menggunakan mekanisme di atas secara otomatis: suatu program dapat menginstal pengendali SIGHUP alternatif (menggunakan sigaction(2)), atau dapat memilih untuk bergabung dengan sesi baru ( setsid(2)).
  • Anda dapat menjalankan screenatau tmux, yang mengalokasikan pseudo-TTY untuk menjalankan sesi dengan shell yang tidak menerima SIGHUP ketika koneksi SSH mati. SIGHUP tidak diteruskan dari sesi SSH ke sesi layar / tmux.

Kebetulan, cara alternatif untuk menangani koneksi SSH yang tidak dapat diandalkan adalah dengan menggunakan protokol Mosh . Mosh berjalan di atas UDP, jadi tidak ada koneksi TCP yang berisiko disetel ulang.

200_sukses
sumber
Bacaan lebih lanjut: Perbedaan antara nohup, disown dan & .
200_sukses
1

Ya, program yang berjalan di atas SSH akan bergantung pada outputnya pergi ke suatu tempat. Jika koneksi lambat, output harus di buffer di suatu tempat, dan buffer tidak dapat tanpa batas, sehingga program harus diblokir jika diisi.

Perhatikan bahwa output mungkin tidak harus pergi ke terminal: pertimbangkan menjalankan sesuatu seperti

ssh user@somewhere "cat file.txt" > file.txt

Ini pada dasarnya akan menyalin file. Agar ini berfungsi, laju output kucing harus cocok dengan koneksi: harus jelas bahwa kehilangan bagian output dari tengah tidak dapat diterima.

Layar akan mengubah situasi di mana ia bertindak seperti terminal dan akan menyimpan apa yang seharusnya ditampilkan "pada jendela terminal" (plus scrollback). Tidak perlu mengingat semua output program Anda, hanya bagian-bagian yang sesuai dengan "jendela" dan scrollback. Secara default, layar akan menunggu koneksi yang lambat (memblokir program), tetapi itu dapat dikonfigurasikan untuk mendeteksi koneksi yang macet dengan mengatur "nonblock on".

Dari halaman manual:

nonblock [hidup | mati | numsecs]

Beri tahu layar cara menangani antarmuka pengguna (tampilan) yang berhenti menerima output. Ini bisa terjadi jika pengguna menekan ^ S atau koneksi TCP / modem terputus tetapi tidak ada hangup yang diterima. Jika nonblock dimatikan (ini adalah default) layar menunggu sampai layar restart untuk menerima output. Jika nonblock aktif, layar menunggu sampai batas waktu tercapai (on diperlakukan sebagai 1s). Jika tampilan masih tidak menerima karakter, layar akan menganggapnya "diblokir" dan berhenti mengirim karakter ke sana. Jika suatu saat restart untuk menerima karakter, layar akan membuka blokir tampilan dan menampilkan kembali isi jendela yang diperbarui.

Pemutusan berbeda dari koneksi yang lambat. SSH biasa tidak dapat pulih darinya secara otomatis, sehingga program Anda akan menerima SIGHUP. Di sisi lain, layar akan mendeteksi pemutusan, melepaskan dan kembali ke buffering lokal sampai layar disambungkan kembali. Ini tidak akan memblokir program yang sedang berjalan.

(Pengaturan nonblock 1pada Anda .screenrcadalah penting jika Anda menjalankan sesuatu seperti irssi yang akan terus menghasilkan output tetapi masih harus berbicara dengan jaringan pada saat yang sama. Memblokir akan menyebabkan terputusnya sambungan dari IRC, yang sangat menyebalkan ...)

ilkkachu
sumber