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