सवाल एसएसएच में टर्मिनल आवंटित करने का क्या फायदा है?


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

ssh user@host sudo thing

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


56
2018-05-06 14:06


मूल


> मुझे याद दिलाया गया है कि एसएसएच एक psuedo-tty आवंटित नहीं करता क्या होता है? यह समझने के लिए सवाल समृद्ध होगा कि समस्या क्या है। - Air
@Air कोई समस्या नहीं है जिसे मैं ठीक करने की कोशिश कर रहा था। एसएसएच को लागू करने में एक विकल्प था कि मैं समझने की कोशिश कर रहा था। सवाल बहुत स्पष्ट है और एंड्रयू बी द्वारा जवाब अच्छी तरह से सवाल को संबोधित करता है। उत्तर इस तरह संक्षेप में किया जा सकता है: चल रहा है ssh -t हमेशा खराब होता है क्योंकि इससे कुछ कमांड अजीब तरीके से तोड़ सकते हैं। जबकि, एक कमांड चलाने के लिए जिसे एक पीटीई की आवश्यकता होती है, एक परिणाम के बिना एक स्पष्ट त्रुटि संदेश में आपको टर्मिनल की आवश्यकता होती है। - Chas. Owens


जवाब:


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

STDIN

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

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

आप अपनी खुद की खोल स्क्रिप्ट में टर्मिनल की उपस्थिति के लिए भी परीक्षण कर सकते हैं। बैश के नए संस्करणों के साथ एसटीडीआईएन का परीक्षण करने के लिए:

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

STDOUT

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

पहले जैसा ही बैश परीक्षण है, लेकिन STDOUT के लिए:

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

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

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


62
2018-05-06 15:02



एक को यह धारणा मिलती है कि मैंने एक टीम पर काम किया है जिसने ऐसा किया है ... - Andrew B


एसएसएच बचने के पात्र और बाइनरी फाइलों का स्थानांतरण

एक लाभ जिसका उल्लेख अन्य उत्तरों में नहीं किया गया है वह यह है कि जब संचालन होता है एक छद्म टर्मिनल के बिना, एसएसएच अक्षर से बचें जैसे कि ~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

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

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


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

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

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

आप अभी भी एक छद्म टर्मिनल आवंटित करने के लिए ओपनएसएसएच क्लाइंट को मजबूर कर सकते हैं -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.

24
2018-01-04 16:10



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


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

/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.

3
2017-08-01 12:51



अच्छा है लेकिन आउटपुट इंडेंट किया गया है /: क्या आपको यह पता चल जाता है कि क्या आप ऑटो कैरिज कर सकते हैं-इसे वापस करें (यूनिक्स की तरह)? - Boop


पिछड़े-संगतता के बारे में सोचें।

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

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


1
2018-05-06 17:24





से 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.

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

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


0
2018-05-06 14:45



यह सवाल का जवाब नहीं देता है। मुझे पहले से ही एक छद्म-टीटी आवंटित करने के बारे में पता है। मैं जानना चाहता हूं कि मुझे हमेशा एक आवंटित क्यों नहीं करना चाहिए। - Chas. Owens
@ चास। ओवेन्स क्योंकि, जैसा कि मैंने जवाब में बताया कुछ एसएसएच सर्वर करते हैं नहीं टीटीआई एक्सेस की अनुमति दें और अगर आप सर्वर से अनुरोध करते हैं तो यह कनेक्शन छोड़ देगा। - Nathan C
मुझे लगता है कि आपको अपनी कुछ शब्दावली उलझन में मिल रही है। यह सिर्फ एक खोल नहीं है क्योंकि एक पीटीई इसके साथ जुड़ा हुआ है। आम तौर पर तीन प्रकार के खोल होते हैं: non-interactive, interactive, तथा login। login अन्य दो शैल प्रकारों की एक अतिरिक्त विशेषता है। इन तीनों के क्रमपरिवर्तन यह निर्धारित करते हैं कि लॉगिन पर कौन सी फाइलें सोर्स की गई हैं, जो बदले में पर्यावरण को कैसे शुरू किया जाएगा। (चर, जैसा कि आप उल्लेख कर रहे थे) - Andrew B
@AndrewB आप सही हैं ... मैंने इस सवाल से कुछ भी सीखा। :) - Nathan C