Bağlantı kapatıldığında “tail -f” adı verilen uzaktan sonlandırma nasıl yapılır?


24

Sadece yürütme eğer fark ssh user@remote_host tail -f /some/file, daha sonra tail -f /some/fileremote_host ssh bağlantısı kapalı olsa bile çalışan tutar!

Böylece, birkaç bağlantı kurduktan ve bağlantıyı kestikten sonra, koşu sayısı tail -f /some/fileartar. Gerçekten tail -fssh bağlantısı kapalı olduğunda sonlandırmak nasıl ?

Yanıtlar:


33

İçinde

ssh host tail -f file

sshİstemci bağlanır sshdüzerinde sunucuya hostTCP bağlantısı üzerinden. stdout bir boruya yönlendirilmiş olarak sshdçalışır tail -f. sshdborunun diğer ucundan gelenleri okur ve sshmüşteriye göndermek için onu sshd protokolünde içine alır . ile ( rshd, tailstdout'u direkt olarak yuva, ama olurdu sshdşifreleme ekler ve tek bir TCP bağlantısında çok borulara başvurmak zorunda (bağlantı noktası / madde / X11 / tünel yönlendirme, standart hataya için gibi çeşitli akışları) multipleks edebilir).

CTRL-C tuşlarına bastığınızda, sshistemciye bir SIGINT gönderilir . Bu sshölüme neden olur . Öldüğünde, TCP bağlantısı kapalıdır. Ve bu nedenle, üzerinde host, sshdölür de. tailÖldürülmedi, ama stdoutu artık diğer ucunda okuyucu bulunmayan bir boru. Böylece, bir dahaki sefere stdout'una bir şeyler yazdığında, bir SIGPIPE alacak ve ölecek.

İçinde:

ssh -t host 'tail -f file'

Bunun yerine bir boru ile olma arasında iletişim dışında aynı şey sshdve tailbir sözde-terminali üzerinden gerçekleştirilir. tailstdout bir köle sözde terminali (benzeri /dev/pts/12) ve ana tarafa yazılan her ne tailise read(muhtemelen tty çizgi disiplini tarafından değiştirilmiş) müşteriye sshdkapsüllenmiş olarak gönderilir ssh.

İstemci tarafında, ile -t, sshkoyar terminali içinde rawmod. Özellikle, terminal kanonik modunu ve terminal sinyal işlemesini devre dışı bırakır.

Bu nedenle, tuşuna bastığınızda Ctrl+C, müşterinin terminal hattı disiplini yerine sshişe bir SIGINT gönderme , bu sadece ^Cbağlantı üzerine karakter gönderir sshdve sshdbunu ^Cuzak terminalin ana tarafına yazar . Ve uzaktan terminalinin hat disiplin bir gönderir SIGINTiçin tail. tailsonra ölür, sshdbağlantıdan çıkar ve bağlantıyı kapatır ve sshsona erer (aksi halde hala liman iletimleriyle veya diğer işlerle meşgul değilse).

Ayrıca, ile -t, eğer sshistemci kalıpları (örneğin girerseniz ~.), bağlantı kapatılır ve sshdölür. Sonuç olarak, bir SIGHUP'a gönderilecek tail.

Şimdi, kullanmanın -tyan etkileri olduğuna dikkat edin . Örneğin, varsayılan terminal ayarlarında, \nkarakterler \r\nuzak sisteme bağlı olarak dönüştürülür ve daha fazla şey olabilir; bu nedenle stty -opostbu çıkış amaçlanmadıysa, uzak ana bilgisayarda bir (çıkış sonrası işlemeyi devre dışı bırakmak için) yayınlamak isteyebilirsiniz. bir 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

-t/ Kullanmanın başka bir sakıncası, -ttstdout ve stderr'nin istemcide ayırt edilmemesidir. Remote komutunun stdout ve stderr'si sshmüşterinin stdout'una yazılacaktır :

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1

Böyle ayrıntılı bir açıklama için çok teşekkür ederim! Keşke iki cevabı kabul edebilseydim ..
Dmitry Frank

"ile -tise, sshistemci kalıpları (örneğin girerseniz ~.)" nedir ~.tekrar?
x-yuri

1
@ x-yuri, ~.istemcinin bağlantısını kesmek için girdiğiniz çıkış dizisidir. Detaylar man sshiçin bakınız.
Stéphane Chazelas

11

Uzak tarafta terminal tahsisine ihtiyacınız var:

ssh -t user@remote_host tail -f /some/file

ya da

ssh -tt user@remote_host tail -f /some/file

1
Teşekkürler, hem -tveya -tteserleri. Ancak bunun gerçek nedenini hala anlayamıyorum: diyelim ki, kabuğu uzaktan çağırdığımda ve bağlantıyı kapattığımda, kabuk sonlandırılıyor. Ama tail -fdeğil. Tabii ki -tseçeneği hakkında zaten okudum man ssh, ama çok yardımcı olmadı. Bazı jenerik ilaçları anlamıyorum ve bazı doktorları bu konuda okumasını ya da muhtemelen kendiniz açıklamasını önerirseniz memnun olurum. Teşekkürler!
Dmitry Frank

2
@DmitryFrank Benim fikrim şudur: Eğer bağlantı koparsa, o zaman a sshdgönderir SIGHUP. Ancak hiçbir terminalin olmadığı yerde hiçbir terminal bağlantısı
kesilemez

Teşekkürler, SIGHUPdiğer sinyalleri okuyacağım , hala neredeyse hiçbir şey bilmeyeceğim.
Dmitry Frank

fyi: Sadece koşmaya çalıştım tail -f, sonra açtım htopve gönderdim SIGHUP( F9-> 1-> tuşlarına basarak Enter) ve tail -fsonlandırıldı! Öyleyse, neden farklı olmalı ..
Dmitry Frank

3
@DmitryFrank Sorunu yanlış anladınız. Sorun değil o tailtepki vermediklerinden SIGHUP. Sorun şu ki SIGHUP, tailsözde bir terminal olmadan gönderilmez . Sen takılarak görebilirsiniz straceiçin tailher iki durumda da.
Hauke ​​Laging
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.