"डॉकर रन "आउटपुट में" इनपुट डिवाइस एक टीटीई नहीं है " का क्या अर्थ है?

यह एक कमांड है जो काम करता है:

$ echo 'hi there' | docker run -i ubuntu cathi there

यह एक कमांड है जो एक त्रुटि संदेश के साथ प्रतिक्रिया करता है:

$ echo 'hi there' | docker run -it ubuntu catthe input device is not a TTY

मैं यह पता लगाना चाहूंगा कि यहां क्या होता है । न केवल "निकालें-टी और यह तय हो जाएगा" ।

मुझे पता है कि docker run's -t विकल्प "एक छद्म-टीटीई आवंटित करें" के लिए खड़ा है, और मैंने पढ़ा है टीटीवाई का क्या अर्थ है, इसका ऐतिहासिक अवलोकन, लेकिन इससे मुझे यह समझने में मदद नहीं मिली कि यहां किस तरह के अनुबंध का उल्लंघन किया गया है ।

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

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

तो

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

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

अब के लिए " टी एंड quot;, यह कहता है, मुख्य प्रक्रिया के अंदर डोकर है कि अपने इनपुट है एक टर्मिनल डिवाइस.

तो

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

यदि आप सीटीआरएल+सी भेजते हैं, तो आपको अपना खोल वापस मिल जाता है, लेकिन यदि आप कोशिश करते हैं 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's इनपुट? ऐसा इसलिए है क्योंकि कमांड इनपुट को अलग तरह से मानते हैं यदि यह टर्मिनल है । यह भी उदाहरण के द्वारा सबसे अच्छा सचित्र है

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

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

यह जवाब मुझे अपना सिर लपेटने में मदद की:

  • डिफ़ॉल्ट रूप से (बिना न तो -i न ही -t विकल्प) एक डॉकर कंटेनर केवल अपना आउटपुट टोस्टडआउट भेजता है,
  • साथ में -i विकल्प एसटीडीआईएन से कनेक्शन आता है,
  • -t विकल्प टर्मिनल इंटरफ़ेस ड्राइवर में खींचता है, कि काम करता है के शीर्ष पर STDIN/STDOUT. और जब एक टर्मिनल ड्राइवर को अंदर खींचा जाता है, तो एक कंटेनर के साथ संचार के अनुरूप होना चाहिए टर्मिनल इंटरफ़ेस प्रोटोकॉल. एक स्ट्रिंग पाइपिंग नहीं करता है ।

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

जब आप अपने जैसे डॉकर में एक कमांड पाइप करते हैं echo उदाहरण दिखाता है, वह पाइप इनपुट है, और उस पाइप में टीटीई इंटरफ़ेस नहीं है, यह सिर्फ पाठ की एक धारा है । इसके साथ एक टीटीई बनाने का प्रयास विफल हो जाएगा क्योंकि त्रुटि संदेश इंगित करता है ।

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

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