टी एल; डॉ
उपयोग न करें -t। -tरिमोट होस्ट पर एक छद्म टर्मिनल शामिल है और इसका उपयोग केवल टर्मिनल से दृश्य अनुप्रयोगों को चलाने के लिए किया जाना चाहिए।
व्याख्या
लाइनफीड चरित्र (जिसे न्यूलाइन या के रूप में भी जाना जाता है \n) वह है जो टर्मिनल पर भेजे जाने पर टर्मिनल को अपने कर्सर को नीचे ले जाने के लिए कहता है।
फिर भी, जब आप seq 3एक टर्मिनल में दौड़ते हैं , तो वह कुछ ऐसा seqलिखता 1\n2\n3\nहै /dev/pts/0, जिसे आप नहीं देखते हैं:
1
2
3
परंतु
1
2
3
ऐसा क्यों है?
दरअसल, जब seq 3(या ssh host seq 3उस मामले के लिए) लिखते हैं 1\n2\n3\n, तो टर्मिनल देखता है 1\r\n2\r\n3\r\n। यही है, लाइन-फीड को कैरिज-रिटर्न (जिस पर टर्मिनल अपने कर्सर को स्क्रीन के बाईं ओर वापस ले जाते हैं) और लाइन-फीड में अनुवाद किया गया है।
यह टर्मिनल डिवाइस ड्राइवर द्वारा किया जाता है। अधिक सटीक रूप से, टर्मिनल (या छद्म टर्मिनल) डिवाइस के लाइन-डिस्क्रिप्शन द्वारा, एक सॉफ्टवेयर मॉड्यूल जो कर्नेल में रहता है।
आप sttyकमांड के साथ उस लाइन अनुशासन के व्यवहार को नियंत्रित कर सकते हैं । LF-> CRLFका अनुवाद चालू है
stty onlcr
(जो आमतौर पर डिफ़ॉल्ट रूप से सक्षम होता है)। आप इसे बंद कर सकते हैं:
stty -onlcr
या आप सभी आउटपुट प्रोसेसिंग को बंद कर सकते हैं:
stty -opost
यदि आप ऐसा करते हैं और चलाते हैं seq 3, तो आप देखेंगे:
$ stty -onlcr; seq 3
1
2
3
जैसा सोचा था।
अब, जब आप करते हैं:
seq 3 > some-file
seqअब टर्मिनल पर नहीं लिख रहा है, यह एक फ़ाइल में लिख रहा है, कोई अनुवाद नहीं हो रहा है। तो some-fileहोता है 1\n2\n3\n। अनुवाद केवल एक टर्मिनल डिवाइस पर लिखते समय किया जाता है। और यह केवल प्रदर्शन के लिए किया गया है।
इसी तरह, जब आप करते हैं:
ssh host seq 3
sshइस बात की 1\n2\n3\nपरवाह किए बिना कि sshआउटपुट किस ओर जाता है।
वास्तव में क्या होता है कि seq 3कमांड को hostउसके स्टडआउट से पाइप पर रीडायरेक्ट किया जाता है। sshमेजबान पर सर्वर पाइप के दूसरे छोर पढ़ता है और इस पर अपने को एन्क्रिप्टेड चैनल भेज sshग्राहक और sshग्राहक इसे अपनी stdout पर एक छद्म टर्मिनल डिवाइस है, जहां लिखते हैं, आपके मामले में LFरों में अनुवाद कर रहे हैं CRLFप्रदर्शन के लिए।
कई इंटरएक्टिव अनुप्रयोग अलग व्यवहार करते हैं जब उनका स्टडआउट टर्मिनल नहीं होता है। उदाहरण के लिए, यदि आप चलाते हैं:
ssh host vi
viयह पसंद नहीं है, यह अपने उत्पादन एक पाइप के लिए जा रहा पसंद नहीं है। यह सोचता है कि यह एक उपकरण से बात नहीं कर रहा है जो उदाहरण के लिए कर्सर पोजिशनिंग एस्केप सीक्वेंस को समझने में सक्षम है।
तो sshउसके लिए -tविकल्प है। उस विकल्प के साथ, होस्ट पर ssh सर्वर एक छद्म टर्मिनल डिवाइस बनाता है और बनाता है कि stdout (और stdin, और stderr) vi। क्या viहै कि टर्मिनल डिवाइस पर लिखते हैं कि दूरदराज के छद्म टर्मिनल लाइन अनुशासन के माध्यम से चला जाता है और द्वारा पढ़ा जाता है sshसर्वर और करने के लिए एन्क्रिप्टेड चैनल के द्वारा भेजा sshग्राहक। यह पहले की तरह ही है सिवाय इसके कि एक पाइप का उपयोग करने के बजाय , sshसर्वर एक छद्म टर्मिनल का उपयोग करता है ।
अन्य अंतर यह है कि क्लाइंट की तरफ, sshक्लाइंट टर्मिनल को rawमोड में सेट करता है। इसका मतलब है कि कोई अनुवाद वहां नहीं किया गया है ( opostअक्षम है और अन्य इनपुट-साइड व्यवहार भी है)। उदाहरण के लिए, जब आप टाइप करते हैं, तो Ctrl-Cव्यवधान डालने के बजाय ssh, उस ^Cवर्ण को दूरस्थ पक्ष में भेज दिया जाता है, जहां दूरस्थ छद्म-टर्मिनल का लाइन अनुशासन दूरस्थ कमांड को व्यवधान भेजता है ।
जब तुम करोगे:
ssh -t host seq 3
seq 31\n2\n3\nअपने स्टडआउट को लिखते हैं , जो एक छद्म टर्मिनल डिवाइस है। इसकी वजह से onlcr, होस्ट करने के लिए इसका अनुवाद हो जाता है 1\r\n2\r\n3\r\nऔर आपको एन्क्रिप्टेड चैनल पर भेज दिया जाता है। आपकी ओर से कोई अनुवाद ( onlcrअक्षम) नहीं है, इसलिए 1\r\n2\r\n3\r\nअछूता ( rawमोड के कारण) प्रदर्शित होता है और आपके टर्मिनल विनियामक की स्क्रीन पर सही ढंग से दिखाई देता है।
अब, यदि आप करते हैं:
ssh -t host seq 3 > some-file
ऊपर से कोई अंतर नहीं है। sshएक ही बात लिखेंगे: 1\r\n2\r\n3\r\nलेकिन इस बार में some-file।
इसलिए मूल रूप से सभी के LFउत्पादन seqमें अनुवाद किया CRLFगया है some-file।
यदि आप ऐसा ही करते हैं:
ssh -t host cat remote-file > local-file
सभी LFवर्णों (0x0a बाइट्स) का CRLF (0x0d 0x0a) में अनुवाद किया जा रहा है।
शायद यही कारण है कि आपकी फ़ाइल में भ्रष्टाचार का कारण है। दूसरी छोटी फ़ाइल के मामले में, यह सिर्फ इतना होता है कि फ़ाइल में 0x0a बाइट्स नहीं होते हैं, इसलिए कोई भ्रष्टाचार नहीं है।
ध्यान दें कि आप अलग-अलग प्रकार की भ्रष्टाचार के साथ अलग-अलग प्रकार की सेटिंग प्राप्त कर सकते हैं। भ्रष्टाचार से जुड़ा एक और संभावित प्रकार -tहै, यदि आपकी स्टार्टअप फाइलें host( ~/.bashrc, ~/.ssh/rc...) उनके स्टाडर पर चीजें लिखती हैं, क्योंकि -tरिमोट शेल के स्टडआउट और स्टडर के साथ अंत में ssh's' स्टडआउट में विलय हो जाता है (वे दोनों छद्म में जाते हैं। -टर्मिनल डिवाइस)।
आप नहीं चाहते कि रिमोट catकिसी टर्मिनल डिवाइस को आउटपुट दे।
तुम्हें चाहिए:
ssh host cat remote-file > local-file
तुम यह कर सकते थे:
ssh -t host 'stty -opost; cat remote-file` > local-file
यही कारण है कि (छोड़कर काम करेगा लेखन stderr को भ्रष्टाचार मामले में ऊपर चर्चा), लेकिन फिर भी है कि उप इष्टतम किया जाएगा के रूप में आपको लगता है कि अनावश्यक छद्म टर्मिनल परत पर चल रहा होगा host।
कुछ और मजेदार:
$ ssh localhost echo | od -tx1
0000000 0a
0000001
ठीक है।
$ ssh -t localhost echo | od -tx1
0000000 0d 0a
0000002
LF का अनुवाद किया CRLF
$ ssh -t localhost 'stty -opost; echo' | od -tx1
0000000 0a
0000001
ठीक है फिर से।
$ ssh -t localhost 'stty olcuc; echo x'
X
यह आउटपुट पोस्ट-प्रोसेसिंग का एक और रूप है जो टर्मिनल लाइन अनुशासन द्वारा किया जा सकता है।
$ echo x | ssh -t localhost 'stty -opost; echo' | od -tx1
Pseudo-terminal will not be allocated because stdin is not a terminal.
stty: standard input: Inappropriate ioctl for device
0000000 0a
0000001
sshसर्वर को एक छद्म टर्मिनल का उपयोग करने के लिए बताने से मना कर दिया जब उसका स्वयं का इनपुट टर्मिनल नहीं है। आप इसे -ttहालांकि के साथ मजबूर कर सकते हैं :
$ echo x | ssh -tt localhost 'stty -opost; echo' | od -tx1
0000000 x \r \n \n
0000004
इनपुट साइड पर लाइन अनुशासन बहुत कुछ करता है।
यहाँ, echoइसके इनपुट को नहीं पढ़ा है और न ही आउटपुट के लिए कहा गया है कि x\r\n\nयह कहाँ से आता है? यह echoदूरस्थ छद्म टर्मिनल ( stty echo) का स्थानीय है । sshसर्वर खिला है x\nयह दूरदराज के छद्म टर्मिनल के मालिक ओर करने के लिए ग्राहक से पढ़ें। और उस पंक्ति का अनुशासन उसे वापस लाता है (पहले stty opostचलाया जाता है जिसके कारण हमें a CRLFऔर not दिखाई देता है LF)। यह इस बात से स्वतंत्र है कि दूरस्थ अनुप्रयोग स्टड से कुछ भी पढ़ता है या नहीं।
$ (sleep 1; printf '\03') | ssh -tt localhost 'trap "echo ouch" INT; sleep 2'
^Couch
0x3चरित्र के रूप में वापस गूँजती है ^C( ^और C) की वजह से stty echoctlऔर खोल और नींद क्योंकि एक SIGINT प्राप्त stty isig।
इसलिए जबकि:
ssh -t host cat remote-file > local-file
काफी बुरा है, लेकिन
ssh -tt host 'cat > remote-file' < local-file
फ़ाइलों को दूसरे तरीके से स्थानांतरित करना बहुत बुरा है। > वामो अनुवाद, लेकिन यह भी सभी विशेष वर्ण के साथ समस्याओं (- आप कुछ सीआर मिल जाएगा ^C, ^Z, ^D, ^?, ^S...) और भी दूरदराज के catEOF नहीं देखेंगे के अंत जब local-fileतक पहुँच जाता है, जब ^Dएक के बाद भेज दिया जाता है \r, \nया किसी अन्य की ^Dतरह जब cat > fileअपने टर्मिनल में कर रहे हैं ।
-tविकल्प है, जो हस्तांतरण को तोड़ता है। उपयोग न करें-tया-T, जब तक कि आपको एक बहुत विशिष्ट कारण के लिए उनकी आवश्यकता न हो। अधिकांश मामलों में डिफ़ॉल्ट काम करता है, इसलिए उन विकल्पों की बहुत कम आवश्यकता होती है।