Saya baru menyadari bahwa jika saya menjalankan ssh [email protected]_host tail -f /some/file , lalu tail -f /some/file tetap berjalan di remote_host meskipun koneksi ssh ditutup!
Jadi, setelah beberapa kali terhubung dan terputus, jumlah tail -f /some/file yang berjalan tumbuh. Bagaimana sebenarnya menghentikan tail -f kapan koneksi ssh ditutup?
Jawaban yang Diterima:
Dalam
ssh host tail -f file
ssh klien terhubung ke sshd server di host melalui koneksi TCP. sshd menjalankan tail -f dengan stdoutnya dialihkan ke pipa. sshd membaca apa yang datang dari ujung pipa yang lain dan merangkumnya dalam protokol sshd untuk dikirim ke ssh klien. (dengan rshd , tail stdout akan menjadi soket secara langsung, tetapi sshd menambahkan enkripsi dan mampu menggandakan beberapa aliran (seperti untuk port/agent/X11/tunnel redirection, stderr) pada satu koneksi TCP sehingga harus menggunakan pipa).
Saat Anda menekan CTRL-C, sebuah SIGINT dikirim ke ssh klien. Itu menyebabkan ssh untuk mati. Setelah sekarat koneksi TCP ditutup. Oleh karena itu, pada host , sshd mati juga. tail tidak terbunuh, tetapi stdout-nya sekarang menjadi pipa tanpa pembaca di ujung yang lain. Jadi, saat berikutnya ia menulis sesuatu ke stdout-nya, ia akan menerima SIGPIPE dan mati.
Dalam:
ssh -t host 'tail -f file'
Itu hal yang sama kecuali bahwa alih-alih dengan pipa, komunikasi antara sshd dan tail adalah melalui pseudo-terminal. tail 's stdout adalah terminal semu budak (seperti /dev/pts/12 ) dan apa pun tail tulis ada read di sisi master (mungkin dimodifikasi oleh disiplin garis tty) oleh sshd dan dikirim dalam bentuk enkapsulasi ke ssh klien.
Di sisi klien, dengan -t , ssh menempatkan terminal dalam raw mode. Secara khusus, itu menonaktifkan mode kanonik terminal dan penanganan sinyal terminal.
Jadi, ketika Anda menekan Ctrl+C , alih-alih disiplin jalur terminal klien mengirim SIGINT ke ssh pekerjaan, yang hanya mengirimkan ^C karakter melalui koneksi ke sshd dan sshd menulis bahwa ^C ke sisi master terminal jarak jauh. Dan disiplin baris dari terminal jarak jauh mengirimkan SIGINT ke tail . tail kemudian mati, dan sshd keluar dan menutup koneksi dan ssh berakhir (jika tidak, masih sibuk dengan penerusan porta atau lainnya).
Juga, dengan -t , jika ssh klien mati (misalnya jika Anda memasukkan ~. ), koneksi ditutup dan sshd mati. Akibatnya, SIGHUP akan dikirim ke tail .
Sekarang, berhati-hatilah menggunakan -t memiliki efek samping. Misalnya, dengan pengaturan terminal default, \n karakter diubah menjadi \r\n dan lebih banyak hal mungkin terjadi tergantung pada sistem jarak jauh, jadi Anda mungkin ingin mengeluarkan stty -opost (untuk menonaktifkan pasca-pemrosesan keluaran) pada host jarak jauh jika keluaran tersebut tidak ditujukan untuk terminal:
$ ssh localhost 'echo x' | hd
00000000 78 0a |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000 78 0d 0a |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000 78 0a |x.|
00000002
Kelemahan lain menggunakan -t /-tt adalah bahwa stdout dan stderr tidak dibedakan pada klien. Baik stdout dan stderr dari perintah jarak jauh akan ditulis ke ssh tujuan klien:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1