कनेक्शन बंद होने पर दूरस्थ रूप से "पूंछ-एफ" कहा जाता है?


24

मैंने अभी देखा कि अगर मैं निष्पादित करता हूं ssh user@remote_host tail -f /some/file, तो tail -f /some/filessh कनेक्शन बंद होने पर भी रिमोट_होस्ट पर चलता रहता है!

तो, कई कनेक्ट और डिस्कनेक्ट के बाद, रनिंग की संख्या tail -f /some/fileबढ़ती है। tail -fजब ssh कनेक्शन बंद हो तो वास्तव में कैसे समाप्त करें ?

जवाबों:


33

में

ssh host tail -f file

sshग्राहक को जोड़ता है sshdपर सर्वर hostएक TCP कनेक्शन पर। sshdरन tail -fअपने stdout के साथ एक पाइप दिया करता था। sshdपढ़ता है कि पाइप के दूसरे छोर से क्या आ रहा है और sshक्लाइंट को भेजने के लिए इसे sshd प्रोटोकॉल में इनकैप्सुलेट करता है । (के साथ rshd, tailस्टडआउट सीधे सॉकेट होता, लेकिन sshdएन्क्रिप्शन जोड़ता है और एकल टीसीपी कनेक्शन पर कई धाराओं (जैसे पोर्ट / एजेंट / एक्स 11 / टनल पुनर्निर्देशन, स्टेडर के लिए मल्टीप्लेक्स करने में सक्षम है) ताकि पाइप का सहारा लेना पड़े।

जब आप CTRL-C दबाते हैं, तो sshक्लाइंट को एक SIGINT भेजा जाता है । जो sshमरने का कारण बनता है। मरने पर टीसीपी कनेक्शन बंद हो जाता है। और इसलिए, पर host, sshdसाथ ही मर जाता है।tailमारा नहीं गया है, लेकिन उसका स्टडआउट अब एक पाइप है जिसके दूसरे छोर पर कोई पाठक नहीं है। तो, अगली बार जब यह अपने स्टडआउट के लिए कुछ लिखता है, तो यह एक SIGPIPE प्राप्त करेगा और मर जाएगा।

में:

ssh -t host 'tail -f file'

यह सिवाय इसके कि बजाय एक पाइप के साथ होने का, के बीच संचार में एक ही बात है sshdऔर tailएक छद्म टर्मिनल के माध्यम से है। tail's stdout एक दास छद्म-टर्मिनल (जैसे /dev/pts/12) है और जो कुछ भी tailवहाँ है readवह मास्टर की ओर (संभवतः tty लाइन अनुशासन द्वारा संशोधित) द्वारा sshdऔर sshग्राहक को इनकैप्सुलेट किए जाने पर लिखा जाता है ।

क्लाइंट के साथ -t, sshटर्मिनल को rawमोड में रखता है। विशेष रूप से, जो टर्मिनल कैनोनिकल मोड और टर्मिनल सिग्नल हैंडलिंग को अक्षम करता है।

इसलिए, जब आप प्रेस करते हैं, तो Ctrl+Cग्राहक की टर्मिनल लाइन अनुशासन के बजाय sshनौकरी के लिए एक संकेत भेजते हैं , जो कि ^Cकनेक्शन को चरित्र को भेजता है sshdऔर sshdलिखता है कि ^Cदूरस्थ टर्मिनल के मास्टर पक्ष में। और रिमोट टर्मिनल का लाइन अनुशासन एक भेजता SIGINTहै tailtailतब मर जाता है, और sshdबाहर निकलता है और कनेक्शन को बंद कर देता है और sshसमाप्त कर देता है (यदि यह अन्यथा पोर्ट अग्रेषण या अन्य के साथ व्यस्त नहीं है)।

इसके अलावा, -tयदि sshग्राहक मर जाता है (उदाहरण के लिए यदि आप प्रवेश करते हैं ~.), तो कनेक्शन बंद हो sshdजाता है और मर जाता है। परिणामस्वरूप, एक SITEUP को भेजा जाएगाtail

अब, सावधान रहें कि -tसाइड इफेक्ट्स का उपयोग करना है। उदाहरण के लिए, डिफ़ॉल्ट टर्मिनल सेटिंग्स के साथ, \nवर्णों को परिवर्तित किया जाता है \r\nऔर रिमोट सिस्टम के आधार पर अधिक चीजें हो सकती हैं, इसलिए आप stty -opostदूरस्थ होस्ट पर एक (आउटपुट पोस्ट-प्रोसेसिंग को अक्षम करने के लिए) जारी करना चाह सकते हैं यदि वह आउटपुट के लिए अभिप्रेत नहीं है एक टर्मिनल:

$ 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/ -ttकि stdout और stderr ग्राहक पर अलग नहीं कर रहे हैं। दूरस्थ कमांड के स्टडआउट और स्टॉडर दोनों को sshक्लाइंट के स्टडआउट को लिखा जाएगा :

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

इतनी विस्तृत व्याख्या के लिए आपका बहुत-बहुत धन्यवाद! मेरी इच्छा है कि मैं दो उत्तर स्वीकार करूं ..
दिमित्री फ्रैंक

" -tअगर sshग्राहक मर जाता है (उदाहरण के लिए यदि आप प्रवेश करते हैं ~.)" तो ~.फिर क्या है ?
एक्स-यूरी

1
@ x-yuri, ~.ग्राहक को डिस्कनेक्ट करने के लिए आपके द्वारा दर्ज किया गया एस्केप अनुक्रम है। man sshविवरण के लिए देखें।
स्टीफन चेज़लस

11

आपको दूरस्थ तरफ टर्मिनल आवंटन की आवश्यकता है:

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

या और भी

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

1
धन्यवाद, दोनों -tया -ttकाम करता है। लेकिन मैं अभी भी इसका वास्तविक कारण नहीं समझ सकता: कहते हैं, जब मैं शेल को दूरस्थ रूप से कॉल करता हूं और कनेक्शन बंद करता हूं, तो शेल समाप्त हो जाता है। लेकिन tail -fनहीं है। बेशक मैं पहले ही -tविकल्प के बारे में पढ़ चुका हूँ man ssh, लेकिन इससे बहुत मदद नहीं मिली। ऐसा लगता है कि मैं कुछ जेनरिक को नहीं समझता, और मुझे खुशी होगी अगर आप इसके बारे में पढ़ने के लिए कुछ डॉक्स सुझाते हैं, या शायद खुद इसे समझाते हैं। धन्यवाद!
दिमित्री फ्रैंक

2
@DmitryFrank मेरी समझ यह है: यदि कनेक्शन टूट जाता है तो sshda भेजता है SIGHUP। लेकिन जहां कोई टर्मिनल नहीं है वहां कोई टर्मिनल कनेक्शन हैंगअप नहीं हो सकता है ...
हौके लैजिंग

धन्यवाद, मैं SIGHUPऔर अन्य संकेतों के बारे में पढ़ूंगा, अभी भी इसके बारे में लगभग कुछ भी नहीं जानता।
दिमित्री फ्रैंक

fyi: मैं बस चलाने की कोशिश की tail -f, तो मैं खोला है htopऔर SIGHUPइसे करने के लिए भेजा (दबाकर F9-> 1-> Enter), और tail -fसमाप्त हो गया है! तो, कारण कुछ अलग होना चाहिए ..
दिमित्री फ्रैंक

3
@DmitryFrank आपने समस्या को गलत समझा है। समस्या यह नहीं है कि tailयह प्रतिक्रिया नहीं करेगा SIGHUP। समस्या यह है कि एक छद्म टर्मिनल के बिना SIGHUP** नहीं भेजा जाता है tail। आप देख सकते हैं कि संलग्न द्वारा straceकरने के लिए tailदोनों ही मामलों में।
हौके लैजिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.