“ อุปกรณ์อินพุตไม่ใช่ TTY” หมายถึงอะไรในเอาต์พุต“ นักเทียบท่าเรียกใช้”?


18

นี่คือคำสั่งที่ใช้งานได้:

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

นี่คือคำสั่งที่ตอบสนองด้วยข้อความแสดงข้อผิดพลาด:

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

ฉันต้องการทราบว่าเกิดอะไรขึ้นที่นี่ ไม่ใช่แค่ "ลบ -t และมันจะได้รับการแก้ไข"

ฉันรู้ว่าdocker run's -tตัวเลือกที่ย่อมาจาก 'จัดสรรหลอก TTY' และฉันได้อ่านภาพรวมประวัติศาสตร์ของสิ่ง TTY ย่อมาแต่มันก็ไม่ได้ช่วยให้ฉันเข้าใจสิ่งที่ชนิดของสัญญาการละเมิดที่นี่


มันไม่ซ้ำซ้อนนักเทียบท่าสามารถสร้าง TTY ได้โดยไม่ต้องติดอะไรเลย เอาต์พุตของคุณจะมีอักขระสำหรับสี ฯลฯ แต่เอาต์พุตเทอร์มินัลของคุณจะไม่ถูกไพพ์ลงในอินพุตของคอนเทนเนอร์ ดังนั้นอักขระที่คุณพิมพ์จะเข้าคิวสำหรับคำสั่งถัดไปที่คุณรันหลังจากคำสั่งนักเทียบท่าออก
BMitch

ฉันสามารถเริ่ม tty ภายใน docker ได้ไหม? ฉันมีแอพบางตัวที่หยุดทำงานฉันไม่ได้เรียกใช้ docker ด้วย-tแต่ฉันไม่สามารถแก้ไขคำสั่ง docker start ในการผลิตได้ -tดังนั้นผมจึงต้องการที่จะทำให้แอปคิดว่ามันเริ่มต้นด้วย
mvorisek

คำตอบ:


9

คำตอบนี้ช่วยให้ฉันห่อหัวของฉันไปรอบ ๆ :

  • โดยค่าเริ่มต้น (ไม่มีตัวเลือก-iหรือไม่มี-t) ตัวเชื่อมต่อคอนเทนเนอร์จะส่งเอาต์พุตไปที่ STDOUT เท่านั้น
  • ด้วย-iตัวเลือกมาเชื่อมต่อกับ STDIN
  • -tตัวเลือกดึงในไดรเวอร์อินเตอร์เฟสเทอร์มินัลซึ่งทำงานบน STDIN / STDOUT และเมื่อคนขับถูกดึงขั้วในการสื่อสารกับภาชนะที่ต้องเป็นไปตามโปรโตคอลอินเตอร์เฟซขั้ว การวางท่อสตริงไม่ได้

7

ตอบช้า แต่อาจช่วยใครซักคน

docker run/exec -iจะเชื่อมต่อ STDIN ของคำสั่งภายในคอนเทนเนอร์กับ STDIN ของdocker run/execตัวเอง

ดังนั้น

  • docker run -i alpine catช่วยให้คุณมีบรรทัดว่างรอการป้อนข้อมูล พิมพ์ "สวัสดี" คุณจะได้รับเสียงสะท้อน "สวัสดี" ภาชนะที่จะไม่ออกจนกว่าคุณจะส่ง CTRL + D เพราะกระบวนการหลักคือการรอคอยสำหรับการป้อนข้อมูลจากกระแสอนันต์ที่มีการป้อนข้อมูลที่ขั้วของcatdocker run
  • ในทางกลับกันecho "hello" | docker -i run alpine catจะพิมพ์ "hello" และออกทันทีเพราะcatสังเกตว่ากระแสข้อมูลได้สิ้นสุดลงและยุติตัวเอง

หากคุณลองdocker psหลังจากออกจากข้อใดข้อหนึ่งข้างต้นคุณจะไม่พบคอนเทนเนอร์ที่ใช้งานอยู่ ในทั้งสองกรณี,catตัวเองได้ยกเลิกดังนั้นนักเทียบท่าได้ยกเลิกภาชนะ

ตอนนี้สำหรับ "-t" นี่จะบอกกระบวนการหลักภายในตัวเทียบท่าว่าอินพุตเป็นอุปกรณ์เทอร์มินัล

ดังนั้น

  • docker run -t alpine catจะให้บรรทัดว่าง แต่ถ้าคุณพยายามพิมพ์ "hello" คุณจะไม่ได้เสียงสะท้อนใด ๆ นี่เป็นเพราะขณะที่catเชื่อมต่อกับอินพุตเทอร์มินัลอินพุตนี้ไม่ได้เชื่อมต่อกับอินพุตของคุณ "Hello" catที่คุณพิมพ์ไม่ถึงการป้อนข้อมูลของ catกำลังรออินพุตที่ไม่เคยมาถึง
  • echo "hello" | docker run -t alpine cat จะให้บรรทัดว่างกับคุณและจะไม่ออกจากคอนเทนเนอร์บน CTRL-D แต่คุณจะไม่ได้รับเสียงสะท้อน "สวัสดี" เพราะคุณไม่ได้ผ่าน -i

ถ้าคุณส่ง CTRL + C คุณจะได้เชลล์กลับมา แต่ถ้าลองdocker psตอนนี้คุณจะเห็นว่าcatคอนเทนเนอร์ยังคงทำงานอยู่ นี่เป็นเพราะcatยังรอสตรีมอินพุตที่ไม่เคยปิด ฉันไม่พบการใช้งานที่เป็นประโยชน์สำหรับ-t-iคนเดียวโดยไม่ต้องถูกรวมกับ

ตอนนี้เพื่อ-itร่วมกัน มันบอกแมวว่าอินพุตของมันเป็นขั้วและในเวลาเดียวกันเชื่อมต่อขั้วนี้กับอินพุตdocker runซึ่งเป็นขั้ว docker run/execจะให้แน่ใจว่าการป้อนข้อมูลของตัวเองในความเป็นจริง TTY 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 -uroot -pจะให้พรอมต์รหัสผ่านแก่คุณ หากคุณพิมพ์รหัสผ่านอักขระจะถูกพิมพ์อย่างชัดเจน
  • docker run -i alpine shจะให้บรรทัดที่ว่างกับคุณ หากคุณพิมพ์คำสั่งเช่นlsคุณได้รับผลลัพธ์ แต่คุณจะไม่ได้รับพรอมต์หรือสีที่ส่งออก

ในสองกรณีสุดท้ายคุณจะได้รับพฤติกรรมนี้เพราะmysqlเช่นเดียวกับที่shellไม่ได้รับการรักษาอินพุตเป็น tty และดังนั้นจึงไม่ได้ใช้พฤติกรรมที่เฉพาะเจาะจง tty เช่นปิดบังอินพุตหรือระบายสีเอาท์พุท


4

tty บ่งชี้ว่าคุณมีเทอร์มินัลสิ่งที่จะได้รับจาก xterm หรือหนึ่งในอินเตอร์เฟสบรรทัดคำสั่ง linux จำนวนมาก มันต้องการแป้นพิมพ์และอินเตอร์เฟซเอาท์พุทข้อความที่เกี่ยวข้อง เหตุผลทั่วไปที่ต้องการสิ่งนี้คือการรองรับเอาต์พุตข้อความสีการจัดการชุดคีย์ต่างๆ (เช่นปุ่มลูกศร) และความสามารถในการเลื่อนเคอร์เซอร์ไปทั่วหน้าจอ

เมื่อคุณไพพ์คำสั่งลงในตัวเทียบท่าอย่างที่echoแสดงตัวอย่างไพพ์นั้นคืออินพุตและไพพ์นั้นไม่มีอินเตอร์เฟส tty นั่นเป็นเพียงสตรีมของข้อความ ความพยายามในการสร้าง tty ด้วยที่จะล้มเหลวตามที่ระบุข้อผิดพลาด


ดูเพิ่มเติมที่: stackoverflow.com/a/43099210/596285
BMitch

ยังคงมีช่องว่างสำหรับฉันระหว่าง "คีย์บอร์ดและอินเทอร์เฟซเอาท์พุท" และ "STDIN / STDOUT" เห็นได้ชัดว่าคุณไม่สามารถใช้แนวคิด "ตำแหน่งเคอร์เซอร์" กับ STDOUT เนื่องจาก STDOUT เป็นสตรีมไม่ใช่หน้าจอ ข้อกำหนดอะไรอธิบายถึงอินเทอร์เฟซเอาท์พุทที่เป็นนามธรรม (ฉันเดาว่า) อยู่ด้านบนของ STDOUT?
Mikhail Vasin

1
มันเป็นอินเตอร์เฟสที่ทำงานบน stdin / stdout en.wikipedia.org/wiki/POSIX_terminal_interface
BMitch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.