एक छद्म-TTY आवंटित करने के लिए Docker -t विकल्प के बारे में भ्रमित


206

वास्तव में यह विकल्प क्या करता है? मैं TTY पर बहुत कुछ पढ़ रहा हूँ और अभी भी उलझन में हूँ। मैं -tऔर बस नहीं होने के साथ चारों ओर खेला -iऔर यह उन कार्यक्रमों की तरह लगता है जो उपयोगकर्ता इनपुट के बिना एक त्रुटि फेंकने की उम्मीद करते हैं -t। छद्म-टीटीवाई को सक्षम करने के लिए यह क्यों महत्वपूर्ण है?

जवाबों:


223

-tविकल्प के लिए कैसे यूनिक्स / लिनक्स टर्मिनल का उपयोग संभालती है चला जाता है। अतीत में, एक टर्मिनल एक हार्डलाइन कनेक्शन था, बाद में एक मॉडेम आधारित कनेक्शन। इनमें भौतिक उपकरण चालक थे (वे उपकरण के असली टुकड़े थे)। एक बार सामान्यीकृत नेटवर्क उपयोग में आने के बाद, एक छद्म टर्मिनल चालक विकसित किया गया था। इसका कारण यह है कि यह समझ टर्मिनल क्षमताओं अपने कार्यक्रम में सीधे लिखने के लिए (पर आदमी पृष्ठों को पढ़ने की आवश्यकता के बिना इस्तेमाल किया जा सकता जो जुदाई बनाता है stty, curses)।

तो, उस पृष्ठभूमि के साथ, बिना किसी विकल्प के एक कंटेनर चलाएं और डिफ़ॉल्ट रूप से आपके पास एक स्टडआउट स्ट्रीम (ताकि docker run | <cmd>काम करता है); के साथ चलाने के लिए -i, और आप स्टड स्ट्रीम जोड़ा (इसलिए <cmd> | docker run -iकाम करता है); उपयोग -t, आमतौर पर संयोजन में -itऔर आपके पास एक टर्मिनल ड्राइवर जोड़ा जाता है, जो यदि आप प्रक्रिया के साथ बातचीत कर रहे हैं, तो संभावना है कि आप क्या चाहते हैं। यह मूल रूप से कंटेनर स्टार्ट को टर्मिनल कनेक्शन सत्र की तरह बनाता है।


7
यह शीर्ष उत्तर होना चाहिए। हालांकि यह यहां सबसे अधिक तकनीकी नहीं है, यह -itझंडे के मौलिक व्यवहार की व्याख्या करता है ।
क्रिश खैरा

1
क्रिश से सहमत। मैंने अन्य उत्तर पढ़े और अभी भी पूरी तरह से भ्रमित था। यह उत्तर इसे साफ करता है।
बेन ली

3
हां, शायद यह ध्यान देने योग्य है कि "TTY" अपने आप में "teletypewriter" (AKA "teleprinter") शब्द से आने वाला एक संक्षिप्त नाम है, जो डिवाइस का एक नाम था जो आपको पाठ टाइप करने और एक ही समय में इसे दूर भेजने की अनुमति देता है - जैसे टेलीफोन पाठ के लिए ;-) कोशिश करो docker run -i ubuntuऔर docker run -it ubuntuआप तुरंत अंतर देखेंगे। "-i" आपको कंटेनर को होस्ट से बातचीत के लिए इंतजार करने की अनुमति देता है लेकिन कंसोल (टर्मिनल) से वास्तविक इंटरैक्शन संभव है, जब आप "फ्लैटी-टी" के साथ "ट्टी ड्राइवर" आवंटित करते हैं।
ज़ीगर

क्या मैं डॉकटर के भीतर ट्टी शुरू कर सकता हूं? मेरे पास कुछ ऐप हैं, जो काम करना बंद कर देते हैं, मैं docker को नहीं चलाता -t, लेकिन मैं docker को कमांड को प्रोडक्शन में संशोधित नहीं कर सकता। इसलिए मुझे लगता है कि ऐप को बनाने की आवश्यकता है क्योंकि इसे इसके साथ शुरू किया गया था -t
मावेरेसेक

97

देर से जवाब, लेकिन किसी की मदद कर सकते हैं

docker run/exec -iकंटेनर के अंदर कमांड के STDIN को docker run/execखुद के STDIN से जोड़ेगा ।

इसलिए

  • docker run -i alpine catआपको इनपुट के इंतजार में एक खाली लाइन देता है। टाइप करें "हैलो" आपको एक गूंज "हैलो" मिलती है। जब तक आप भेजते हैं तब तक कंटेनर बाहर नहीं निकलेगा CTRL+ Dक्योंकि मुख्य प्रक्रिया catअनंत स्ट्रीम से इनपुट का इंतजार कर रही है जो कि टर्मिनल इनपुट है docker run
  • दूसरी ओर echo "hello" | docker run -i alpine cat"हैलो" प्रिंट करेगा और तुरंत बाहर निकल जाएगा क्योंकि catनोटिस कि इनपुट स्ट्रीम समाप्त हो गया है और खुद को समाप्त कर देता है।

यदि आप docker psउपरोक्त दोनों में से किसी एक से बाहर निकलने के बाद कोशिश करते हैं, तो आपको कोई भी चलने वाला कंटेनर नहीं मिलेगा। दोनों ही मामलों में, catखुद को समाप्त कर दिया है, इस प्रकार डॉकटर ने कंटेनर को समाप्त कर दिया है।

अब "-t" के लिए, यह डॉकटर के अंदर मुख्य प्रक्रिया को बताता है कि इसका इनपुट एक टर्मिनल डिवाइस है।

इसलिए

  • docker run -t alpine catआपको एक खाली लाइन देगा, लेकिन यदि आप "हैलो" टाइप करने का प्रयास करते हैं, तो आपको कोई प्रतिध्वनि नहीं मिलेगी। ऐसा इसलिए है क्योंकि जब catआप किसी टर्मिनल इनपुट से जुड़े होते हैं, तो यह इनपुट आपके इनपुट से जुड़ा नहीं होता है। आपके द्वारा टाइप किया गया "हैलो" इनपुट तक नहीं पहुंचा catcatउस इनपुट की प्रतीक्षा कर रहा है जो कभी नहीं आता है।
  • echo "hello" | docker run -t alpine catआपको एक खाली लाइन भी देगा और कन्टेनर से बाहर नहीं निकलेगा CTRL- Dलेकिन आपको "हैलो" नहीं मिलेगा क्योंकि आपने पास नहीं किया है-i

यदि आप CTRL+ भेजते हैं C, तो आपको अपना शेल वापस मिल जाता है, लेकिन यदि आप docker psअभी कोशिश करते हैं, तो आप catकंटेनर को अभी भी देखते हैं । ऐसा इसलिए है क्योंकि catअभी भी एक इनपुट स्ट्रीम पर प्रतीक्षा की जा रही है जो कभी बंद नहीं हुई थी। मुझे -tअकेले संयुक्त किए बिना कोई उपयोगी उपयोग नहीं मिला -i

अब, -itएक साथ के लिए। यह बिल्ली को बताता है कि उसका इनपुट एक टर्मिनल है और उसी समय में इस टर्मिनल को उस इनपुट से कनेक्ट करें, docker runजो एक टर्मिनल है। docker run/execयह सुनिश्चित करेगा कि इसका अपना इनपुट वास्तव में इसे पास करने से पहले एक ट्टी है cat। यही कारण है कि input device is not a TTYयदि आप प्रयास करेंगे तो echo "hello" | docker run -it alpine catइस कारण से, क्योंकि इस मामले में, docker runस्वयं का इनपुट पिछली प्रतिध्वनि से पाइप है, न कि टर्मिनल जहां docker runनिष्पादित किया गया है

अंत में, -tयदि -iआपको अपने इनपुट को इनपुट से कनेक्ट करने की चाल चलेगी, तो आपको पास करने की आवश्यकता क्यों होगी cat? ऐसा इसलिए है क्योंकि कमांड इनपुट का उपचार अलग तरह से करता है अगर वह टर्मिनल है। यह भी उदाहरण के द्वारा सबसे अच्छा चित्रित किया गया है

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -pआपको एक पासवर्ड प्रॉम्प्ट देगा। यदि आप पासवर्ड टाइप करते हैं, तो वर्ण स्पष्ट रूप से मुद्रित होते हैं।
  • docker run -i alpine shआपको एक खाली लाइन देगा। यदि आप एक कमांड टाइप करते हैं जैसे कि lsआपको आउटपुट मिलता है, लेकिन आपको प्रॉम्प्ट या रंगीन आउटपुट नहीं मिलेगा।

पिछले दो मामलों में, आपको यह व्यवहार मिलता है क्योंकि mysqlसाथ ही shellइनपुट को टिट्टी के रूप में नहीं मान रहे थे और इस प्रकार इनपुट को मास्क करने या आउटपुट को रंगने जैसे विशिष्ट व्यवहार का उपयोग नहीं किया था।


6
यहाँ सबसे अच्छा जवाब जो वास्तव में मुझे समझता है कि वास्तव में क्या करता है -tऔर -iविकल्प क्या है!
रुस्लान

1
शानदार जवाब जिसने हर सवाल की आशंका जताई
जेम्स मैकिन

@ अहमद गोनिम, बहुत अच्छे जवाब। धन्यवाद। लेकिन "यह इसलिए है क्योंकि कमांड इनपुट का उपचार अलग तरह से करता है यदि यह एक टर्मिनल है", मुझे लगता है कि यह गलत है, सही है? यह होना चाहिए "यह इसलिए है क्योंकि कमांड इनपुट के साथ अलग तरीके से व्यवहार करते हैं यदि यह टर्मिनल नहीं है", है ना?
तुक

@ अहमद गोनिम शीशे की तरह साफ। लेकिन क्या docker run -a = stdin अल्पाइन कैट के बारे में?
HKIT

1
@HKIIT "-a = stdin" स्टड स्ट्रीम को कंटेनर में संलग्न करता है लेकिन मेमोरी आवंटन के बिना। यह -i झंडा है जो स्टडेन स्ट्रीम के लिए कंटेनर में बफर मेमोरी को आवंटित करता है, इसलिए विवरण "STDIN को खुला रखें भले ही संलग्न न हो", जब -i पास की गई मेमोरी अटैचमेंट की परवाह किए बिना स्टड के लिए आवंटित की जाती है। इसके बिना आवंटित मेमोरी स्टड को खाली / ईओएफ पढ़ता है। उदाहरण के लिए बिल्ली कमांड से प्रतिक्रिया देखने के लिए आपको "-a = stdout" शामिल करने की आवश्यकता है: "docker run -i = -a = stdin -a = stdout alpine cat" ... बेशक ऐसा करने की कोई आवश्यकता नहीं है। बस "docker run -i अल्पाइन बिल्ली" चलाएं।
डेविड डी

71

-tतर्क अच्छी तरह से एक गूगल खोज के अनुसार प्रलेखित है नहीं, या उल्लेख अक्सर कई लोगों द्वारा,।

जब आप dockerबैश प्रॉम्प्ट पर (1.8.1 के नवीनतम संस्करण के साथ) टाइप करके सभी docker क्लाइंट तर्कों की सूची प्रदर्शित करते हैं तो यह भी दिखाई नहीं देता है ।

वास्तव में, यदि आप टाइप करके इस तर्क के बारे में विशिष्ट सहायता प्राप्त करने का प्रयास करते हैं docker -t --helpतो यह आश्चर्यजनक अस्पष्ट उत्तर देता है:

ध्वज प्रदान किया गया लेकिन परिभाषित नहीं: -t

इसलिए, आपको इस तर्क के बारे में भ्रमित होने के लिए दोषी नहीं ठहराया जा सकता है!

डॉकर ऑनलाइन दस्तावेज़ में एक उल्लेख है जो कहता है कि यह "एक छद्म-आबंटन आवंटित करें" और अक्सर इसके साथ होता है -i:

https://docs.docker.com/reference/run/

मैंने देखा कि यह jwilder/nginx-proxyनिम्न प्रकार से भयानक डॉकटर कंटेनर के लिए प्रलेखन में इस्तेमाल किया गया है:

docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx

इस मामले में, यह क्या करता है इस डॉकटर कंटेनर के भीतर 'आभासी' tty (बैश कमांड प्रॉम्प्ट / टर्मिनल) के लिए आउटपुट भेजें। फिर आप इस आउटपुट को docker कमांड चलाकर देख सकते हैं docker logs CONTAINERजहां CONTAINERइस कंटेनर की ID के पहले दो अक्षर हैं। यह कंटेनर आईडी टाइप करके पाया जा सकता हैdocker ps -a

मैंने इस -tतर्क का संक्षेप में नीचे दिए गए लिंक में उल्लेख किया है, जहाँ यह कहता है

-tऔर -iझंडे एक छद्म tty का आवंटन और खुले stdin भले ही संलग्न नहीं रहते हैं। यह आपको पारंपरिक वीएम जैसे कंटेनर का उपयोग करने की अनुमति देगा जब तक कि बैश प्रॉम्प्ट चल रहा हो।

https://coreos.com/os/docs/latest/getting-started-with-docker.html

आशा है कि ये आपकी मदद करेगा! मुझे यकीन नहीं है कि यह क्यों प्रलेखित या ज्यादा इस्तेमाल नहीं किया गया है। शायद यह प्रायोगिक है और आगामी संस्करणों में एक प्रलेखित विशेषता के रूप में लागू किया जाएगा।


21
प्रलेखन के लिए पता चलता है docker run --help, नहीं docker -t --help: -t, --tty=false Allocate a pseudo-TTY"
bskaggs

5

मैं -tनिम्नलिखित के बारे में क्या जानता हूं :

docker exec -ti CONTAINER bash- मुझे कंटेनर में "लॉगिन" करने की अनुमति देता है। यह ssh-ing की तरह लगता है (यह नहीं है)।

लेकिन परेशानी तब थी जब मैं एक डेटाबेस को पुनर्स्थापित करना चाहता था।

आमतौर पर मैं करता हूं docker exec -ti mysql.5.7 mysql- यहां मैं कंटेनर में mysql कमांड निष्पादित करता हूं और एक इंटरैक्टिव टर्मिनल प्राप्त करता हूं।

मैंने <dump.sqlपिछली कमांड में जोड़ा ताकि मैं एक db को पुनर्स्थापित कर सकूं। लेकिन इसके साथ असफल रहा cannot enable tty mode on non tty input

-tमदद हटाना । अभी भी समझ में नहीं आता क्यों:

docker exec -i mysql.5.7 mysql < dump.sql

आखिरी काम करता है। उम्मीद है कि इससे लोगों को मदद मिलेगी।


क्या मैं डॉकटर के भीतर ट्टी शुरू कर सकता हूं? मेरे पास कुछ ऐप हैं, जो काम करना बंद कर देते हैं, मैं docker को नहीं चलाता -t, लेकिन मैं docker को कमांड को प्रोडक्शन में संशोधित नहीं कर सकता। इसलिए मुझे लगता है कि ऐप को बनाने की आवश्यकता है क्योंकि इसे इसके साथ शुरू किया गया था -t
मावेरेसेक

1

लिनक्स में जब आप एक कमांड चलाते हैं, तो आपको इसे निष्पादित करने के लिए एक टर्मिनल (ट्टी) की आवश्यकता होती है।

इसलिए जब आप docker से कनेक्ट करना चाहते हैं (या docker कंटेनर में कमांड चलाना), तो आपको विकल्प -t प्रदान करना होगा जो docker कंटेनर के अंदर टर्मिनल के विचार में होता है।


0

हर प्रक्रिया में तीन डेटा स्ट्रीम होते हैं यानी STDIN/ STDOUT/ STDERR। जब कोई प्रक्रिया कंटेनर में चल रही होती है, तो डिफ़ॉल्ट रूप से टर्मिनल कंटेनर में चलने वाली प्रक्रिया के STDOUT स्ट्रीम से जुड़ा होता है। इसलिए docker runटर्मिनल में कमांड चलाने के दौरान सभी आउटपुट स्ट्रीम दिखाई देंगे । लेकिन अगर आप कंटेनर में रनिंग प्रक्रिया को इनपुट प्रदान करना चाहते हैं तो आपको प्रक्रिया के STDIN चैनल से जुड़ना होगा जो कि डिफ़ॉल्ट रूप से नहीं है और यह docker run -iकमांड के साथ किया जाता है ।

-t इंटरैक्टिव / स्वरूपित इनपुट संचालन के लिए उपयोग किया जाता है।


-3

-itडॉकटर को कंटेनर के स्टड से जुड़ा एक छद्म-टीटीवाई आवंटित करने का निर्देश देता है, जिससे कंटेनर में एक इंटरैक्टिव बैश शेल बनता है।

--interactive, -i falseसंलग्न न होने पर भी STDIN को खुला रखें

--tty, -t false एक छद्म-TTY आवंटित करें

https://docs.docker.com/engine/reference/commandline/run/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.