Ssh में टर्मिनल आवंटित नहीं करने का क्या लाभ है?


66

हर बार एक समय में मैं कुछ ऐसा करूंगा

ssh user@host sudo thing

और मुझे याद दिलाया जाता है कि ssh डिफ़ॉल्ट रूप से एक छद्म tty आवंटित नहीं करता है। क्यों नहीं करता है? अगर मैं अलियास हो sshगया तो मुझे क्या लाभ होगा ssh -t?


1
> मुझे याद दिलाया जाता है कि ssh एक psuedo-tty आवंटित नहीं करता है क्या होता है? यह समझने के लिए सवाल को समृद्ध करेगा कि समस्या क्या है।
वायुसेना

5
@ मेरी कोई समस्या नहीं है जिसे मैं ठीक करने की कोशिश कर रहा था। कैसे ssh लागू किया गया है में एक विकल्प था कि मैं समझने की कोशिश कर रहा था। यह प्रश्न बहुत स्पष्ट है और एंड्रयू बी द्वारा दिए गए प्रश्न का उत्तर अच्छी तरह से पता है। उत्तर को इस तरह से अभिव्यक्त किया जा सकता है: रनिंग ssh -tहमेशा खराब होती है क्योंकि इससे कुछ कमांड अजीब तरीके से टूट सकते हैं। जबकि, एक कमांड को चलाने के लिए एक PTY की आवश्यकता होती है, जिसके परिणामस्वरूप एक स्पष्ट त्रुटि संदेश होता है जिसे आपको टर्मिनल की आवश्यकता होती है।
चास।

जवाबों:


73

प्राथमिक अंतर अन्तरक्रियाशीलता की अवधारणा है । यह एक स्क्रिप्ट के अंदर स्थानीय रूप से कमांड चलाने के समान है, बनाम उन्हें अपने आप को टाइप करना। यह अलग है कि एक दूरस्थ कमांड को एक डिफ़ॉल्ट चुनना होगा, और गैर-इंटरैक्टिव सबसे सुरक्षित है। (और आमतौर पर सबसे ईमानदार)

STDIN

  • यदि कोई PTY आवंटित किया जाता है, तो अनुप्रयोग इसका पता लगा सकते हैं और जान सकते हैं कि उपयोगकर्ता को बिना चीजों को तोड़ने के अतिरिक्त इनपुट के लिए संकेत देना सुरक्षित है। ऐसे कई कार्यक्रम हैं जो टर्मिनल मौजूद नहीं होने पर इनपुट के लिए उपयोगकर्ता को संकेत देने के कदम को छोड़ देंगे, और यह एक अच्छी बात है। यह स्क्रिप्ट को अनावश्यक रूप से लटकाने का कारण होगा।
  • आपका इनपुट कमांड की अवधि के लिए रिमोट सर्वर पर भेजा जाएगा। इसमें नियंत्रण अनुक्रम शामिल हैं। जबकि Ctrl-cब्रेक आमतौर पर ssh कमांड पर एक लूप होता है जो तुरंत टूट जाता है, आपके कंट्रोल सीक्वेंस को रिमोट सर्वर पर भेजा जाएगा। इसका परिणाम यह सुनिश्चित करने के लिए कीस्ट्रोके को "हथौड़ा" करने की आवश्यकता है कि यह तब आता है जब नियंत्रण ssh कमांड को छोड़ देता है, लेकिन अगले ssh कमांड शुरू होने से पहले।

मैं ssh -tलावारिस लिपियों, जैसे क्रोनों का उपयोग करने के खिलाफ सावधानी बरतूँगा। एक गैर-संवादात्मक शेल जो दूरस्थ कमांड को इनपुट के लिए अंतःक्रियात्मक व्यवहार करने के लिए कहता है, सभी प्रकार की परेशानी के लिए पूछ रहा है।

आप अपनी स्वयं की शेल स्क्रिप्ट में टर्मिनल की उपस्थिति के लिए भी परीक्षण कर सकते हैं। बाश के नए संस्करणों के साथ STDIN का परीक्षण करने के लिए:

# fd 0 is STDIN
[ -t 0 ]; echo $?

STDOUT

  • जब एलियासिंग sshकरते हैं ssh -t, तो आप अपनी लाइन के सिरों में एक अतिरिक्त गाड़ी वापसी की उम्मीद कर सकते हैं। यह आपको दिखाई नहीं दे सकता है, लेकिन यह वहां है; ^Mजब यह पाइप किया जाएगा तब यह दिखाई देगा cat -e। फिर आपको यह सुनिश्चित करने के अतिरिक्त प्रयास का खर्च करना होगा कि यह नियंत्रण कोड आपके चर को सौंपा नहीं जाता है, खासकर यदि आप उस आउटपुट को डेटाबेस में सम्मिलित करने जा रहे हैं।
  • जोखिम भी है कि प्रोग्राम मान लेंगे कि वे आउटपुट को रेंडर कर सकते हैं जो फ़ाइल पुनर्निर्देशन के लिए अनुकूल नहीं है। आम तौर पर यदि आप किसी फ़ाइल में STDOUT को रीडायरेक्ट करना चाहते थे, तो प्रोग्राम यह पहचान लेगा कि आपका STDOUT एक टर्मिनल नहीं है और किसी भी कलर कोड को छोड़ना है। यदि STDOUT पुनर्निर्देशन ssh क्लाइंट के आउटपुट से है और क्लाइंट के दूरस्थ अंत से संबद्ध PTY है, तो दूरस्थ प्रोग्राम इस तरह का अंतर नहीं कर सकते हैं और आप अपनी आउटपुट फ़ाइल में टर्मिनल कचरा समाप्त कर देंगे। कनेक्शन के दूरस्थ छोर पर एक फ़ाइल में आउटपुट पुनर्निर्देशित करना अभी भी उम्मीद के मुताबिक काम करना चाहिए।

यहाँ पहले की तरह ही बैश टेस्ट है, लेकिन STDOUT के लिए:

# fd 1 is STDOUT
[ -t 1 ]; echo $?

हालांकि इन मुद्दों के आसपास काम करना संभव है, आप अनिवार्य रूप से उनके आसपास स्क्रिप्ट डिजाइन करना भूल जाते हैं। हम सभी किसी न किसी बिंदु पर करते हैं। आपकी टीम के सदस्य यह भी महसूस नहीं कर सकते हैं / याद है कि यह उपनाम जगह में है, जो बदले में आपके लिए समस्याएं खड़ी करेगा जब वे आपके उपनाम का उपयोग करने वाली स्क्रिप्ट लिखते हैं।

अलियासिंग sshको ssh -tबहुत ज्यादा एक मामले में जहां आप के डिजाइन सिद्धांत का उल्लंघन हो जाएगा है कम से कम आश्चर्य की बात है ; लोगों को उन समस्याओं का सामना करना पड़ेगा जो वे उम्मीद नहीं करते हैं और समझ नहीं सकते हैं कि उनके कारण क्या है।


9
एक को लगभग यह आभास हो जाता है कि मैंने एक टीम पर काम किया है जिसने यह किया है ...
एंड्रयू बी

इस उत्तर के दायरे में, यह बहुत अच्छा है। लेकिन प्रश्न में एक व्यापक गुंजाइश थी, अनिवार्य रूप से सभी मतभेदों को जानना चाहते थे (क्या उम्मीद करें)। अतिरिक्त जानकारी: प्रक्रिया के स्तर पर, -t FIRST एक tty आवंटित करेगा और तब एक शेल चलाएगा (वैसे, सोर्सिंग / etc / प्रोफाइल और ~ / .bash_profile) और THEN कमांड को रन करेगा। बिना -t, ssh INSTEAD स्रोत अलग-अलग env फाइल (/etc/bash.bashrc, फिर ~ / .bashrc) और तब आपकी कमांड चलाएगा। इसका मतलब है कि आप प्रत्येक में बहुत भिन्न व्यवहार देख सकते हैं: $ $ PATH, हो सकता है एक bash 'unary' त्रुटि क्योंकि आपके द्वारा ग्रहण की गई ENV var नहीं है ...
Scott Prive

@ क्रॉस्फ़िट हमने एक और उत्तर की टिप्पणियों में लॉगिन गोले बनाम गैर के विषय को कवर किया, लेकिन हम पर्यावरणीय मतभेदों के एक विस्तृत विराम में नहीं गए क्योंकि ओपी ने पहले से ही उनकी विशेष आवश्यकताओं के लिए पूछे गए सवाल पर विचार किया था। कृपया विस्तार से जोड़ने के लिए स्वतंत्र महसूस करें, जहाँ आप ऐसा करने के लिए कमरा देखते हैं क्योंकि यह उन लोगों की मदद कर सकता है जो इस प्रश्नोत्तर पर आते हैं।
एंड्रयू बी

33

SSH वर्ण और बाइनरी फ़ाइलों के हस्तांतरण से बच जाते हैं

एक लाभ जो अन्य उत्तरों में उल्लेख नहीं किया गया है वह यह है कि छद्म टर्मिनल के बिना काम करते समय , SSH भागने के पात्र जैसे समर्थित नहीं~C हैं ; यह द्विआधारी फ़ाइलों को स्थानांतरित करने के लिए कार्यक्रमों के लिए सुरक्षित बनाता है जिसमें ये क्रम हो सकते हैं।

अवधारणा के सुबूत

एक छद्म टर्मिनल का उपयोग कर एक द्विआधारी फ़ाइल की प्रतिलिपि बनाएँ:

$ ssh -t anthony@remote_host 'cat /usr/bin/free' > ~/free
Connection to remote_host closed.

एक छद्म टर्मिनल का उपयोग किए बिना एक बाइनरी फ़ाइल की प्रतिलिपि बनाएँ:

$ ssh anthony@remote_host 'cat /usr/bin/free' > ~/free2

दो फाइलें समान नहीं हैं:

$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ

जिसे छद्म टर्मिनल के साथ कॉपी किया गया था वह दूषित है:

$ chmod +x ~/free*
$ ./free
Segmentation fault

जबकि दूसरा नहीं है:

$ ./free2
             total       used       free     shared    buffers     cached
Mem:       2065496    1980876      84620          0      48264    1502444
-/+ buffers/cache:     430168    1635328
Swap:      4128760        112    4128648

SSH पर फ़ाइलों को स्थानांतरित करना

इस तरह के रूप में कार्यक्रमों के लिए विशेष रूप से महत्वपूर्ण है scpया rsyncजो आंकड़ा अंतरण के लिए SSH का उपयोग करें। एससीपी प्रोटोकॉल कैसे काम करता है इसका विस्तृत विवरण बताता है कि एससीपी प्रोटोकॉल में टेक्स्ट प्रोटोकॉल प्रोटोकॉल और बाइनरी फाइल डेटा का मिश्रण कैसे होता है।


ओपनएसएसएच आपको खुद से बचाने में मदद करता है

यह ध्यान देने योग्य है कि यदि -tध्वज का उपयोग किया जाता है, तो भी OpenSSH sshक्लाइंट एक छद्म-टर्मिनल आवंटित करने से इनकार कर देगा , यदि यह पता लगाता है कि इसकी stdinधारा एक टर्मिनल नहीं है:

$ echo testing | ssh -t anthony@remote_host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb

आप अभी भी OpenSSH क्लाइंट को इसके साथ छद्म टर्मिनल आवंटित करने के लिए बाध्य कर सकते हैं -tt:

$ echo testing | ssh -tt anthony@remote_host 'echo $TERM'
xterm

या तो मामले में, यह (समझदारी से) परवाह नहीं है stdoutया stderrफिर पुनर्निर्देशित किया गया है:

$ ssh -t anthony@remote_host 'echo $TERM' >| ssh_output
Connection to remote_host closed.

2
यह एक बहुत ही दिलचस्प बिंदु था जिस पर मैंने विचार नहीं किया था, इस उत्तर को जोड़ने के लिए धन्यवाद!
जेनी डी

4

दूरस्थ होस्ट पर हमें इस सेटिंग के साथ करना होगा:

/etc/sudoers
...
Defaults requiretty

बिना सूदो के

$ ssh -T user@host echo -e 'foo\\nbar' | cat -e
foo$
bar$

और सूडो के साथ

$ ssh -T user@host sudo echo -e 'foo\\nbar' | cat -e
sudo: sorry, you must have a tty to run sudo

सुडो के साथ हमें अतिरिक्त गाड़ी की वापसी मिलती है

$ ssh -t user@host sudo echo -e 'foo\\nbar' | cat -e
foo^M$
      bar^M$
            Connection to localhost closed.

इसका समाधान ट्रांसलेशन न्यूलाइन को कैरिज रिटर्न-न्यूलाइन के साथ अक्षम करना हैstty -onlcr

$ ssh -t user@host stty -onlcr\; sudo echo -e 'foo\\nbar' | cat -e
foo$
    bar$
        Connection to localhost closed.

1
अच्छा है, लेकिन आउटपुट इंडेंटेड है: क्या आपको पता है कि क्या आप ऑटो कैरिज कर सकते हैं?
बोप

1

पिछड़ेपन-अनुकूलता के बारे में सोचें।

Ssh के 2 प्राथमिक मोड एक tty के साथ इंटरेक्टिव-लॉगिन हैं, और एक tty के बिना निर्दिष्ट-कमांड, क्योंकि वे क्रमशः rloginऔर उसी की सटीक क्षमता rshथे। ssh को प्रतिस्थापन के रूप में सफल होने के लिए सुपरसेट rlogin/ rshसुविधाएँ प्रदान करने की आवश्यकता है ।

तो ssh पैदा होने से पहले चूक का फैसला किया गया था। "मैं चाहता हूं कि एक आदेश निर्दिष्ट करें और एक ट्टी प्राप्त करें" जैसे संयोजनों को नए विकल्पों के साथ एक्सेस करना होगा। खुश रहें कि कम से कम हमारे पास अब वह विकल्प है, जब हम उपयोग कर रहे थे, उसके विपरीत rsh। एन्क्रिप्टेड कनेक्शन प्राप्त करने के लिए हमने किसी उपयोगी सुविधाओं का व्यापार नहीं किया। हमें बोनस सुविधाएँ मिलीं!


0

से man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g. when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

यह आपको दूरस्थ सर्वर के लिए "शेल" प्रकार प्राप्त करने की अनुमति देता है। उन सर्वरों के लिए जो शेल एक्सेस प्रदान नहीं करते हैं, लेकिन SSH (यानी, Github SFTP एक्सेस के लिए एक ज्ञात उदाहरण है) को अनुमति देते हैं, इस ध्वज का उपयोग करने से सर्वर आपके कनेक्शन को अस्वीकार कर देगा।

शेल में आपके सभी पर्यावरणीय चर (जैसे $PATH) होते हैं इसलिए स्क्रिप्ट निष्पादित करने के लिए आमतौर पर काम करने के लिए एक ट्टी की आवश्यकता होती है।


1
इस सवाल का जवाब नहीं है। मुझे पहले से ही पता है कि छद्म ट्टी कैसे आवंटित की जाती है। मैं जानना चाहता हूं कि मुझे हमेशा एक का आवंटन क्यों नहीं करना चाहिए।
चास। ओवेन्स

1
@ Chas.Owens क्योंकि, जैसा कि मैंने उत्तर में बताया है कि कुछ SSH सर्वर ट्टी एक्सेस की अनुमति नहीं देते हैं और यदि आप सर्वर से एक का अनुरोध करते हैं तो यह कनेक्शन को छोड़ देगा।
नाथन सी

5
मुझे लगता है कि आपको अपनी शब्दावली में कुछ गड़बड़ लग रही होगी। यह केवल एक शेल नहीं है क्योंकि एक PTY इसके साथ जुड़ा हुआ है। आम तौर पर खोल के तीन प्रकार हैं: non-interactive, interactive, और loginloginअन्य दो शेल प्रकारों की एक अतिरिक्त विशेषता है। इन तीनों के क्रमपरिवर्तन से पता चलता है कि कौन सी फाइलें लॉगिन पर सुरक्षित हैं, जो बदले में पर्यावरण को कैसे आरंभ किया जाएगा, इस पर प्रभाव डालता है। (चर, जैसा कि आप उल्लेख कर रहे थे)
एंड्रयू बी

3
@AndrewB तुम सही हो ... मैंने इस सवाल से भी कुछ सीखा है। :)
नाथन सी '’
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.