टी एल; डॉ
उपयोग न करें -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 3
1\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
...) और भी दूरदराज के cat
EOF नहीं देखेंगे के अंत जब local-file
तक पहुँच जाता है, जब ^D
एक के बाद भेज दिया जाता है \r
, \n
या किसी अन्य की ^D
तरह जब cat > file
अपने टर्मिनल में कर रहे हैं ।
-t
विकल्प है, जो हस्तांतरण को तोड़ता है। उपयोग न करें-t
या-T
, जब तक कि आपको एक बहुत विशिष्ट कारण के लिए उनकी आवश्यकता न हो। अधिकांश मामलों में डिफ़ॉल्ट काम करता है, इसलिए उन विकल्पों की बहुत कम आवश्यकता होती है।