“Girdi aygıtı bir TTY değildir” tam olarak “docker çalıştırma” çıktısında ne anlama gelir?


18

Bu, çalışan bir komuttur:

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

Bu, bir hata mesajıyla yanıt veren bir komuttur:

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

Burada ne olduğunu tam olarak anlamak istiyorum. Sadece "remove -t ve düzeltilecek" değil.

Bunu biliyorum docker runbireyin -tseçenek 'sahte TTY'yi tahsis' anlamına gelir ve okudum TTY açılımı ne tarihsel bakışlar , ama bana tür bir sözleşmenin burada ihlal olduğunu anlamak yardımcı olmadı.


Bu gereksiz değildir, docker hiçbir şey eklemeden bir TTY oluşturabilir. Çıktınızda renk vb. Karakterler bulunur, ancak terminal çıktınız kabın girdisine eklenmez. Böylece, yazdığınız karakterler docker komutu çıktıktan sonra çalıştırdığınız bir sonraki komut için sıraya alınır.
BMitch

Bağlantı istasyonunda tty'yi başlatabilir miyim? Docker'ı çalıştırmıyorum çalışmayı durduran bazı uygulama var -t, ancak üretimde docker start komutunu değiştiremiyorum. Bu yüzden uygulamayı başladığını düşünmem gerekiyor -t.
mvorisek

Yanıtlar:


9

Bu cevap kafamı sarmama yardımcı oldu:

  • varsayılan olarak ( -ine -tseçenekleri ne de seçenekleri olmadan ) bir Docker konteyneri çıktısını yalnızca STDOUT'a gönderir,
  • ile -iopsiyon STDIN'den bağlantıyı geliyor
  • -tseçeneği , STDIN / STDOUT'un üstünde çalışan bir terminal arabirim sürücüsünü çeker . Ve bir terminal sürücüsü içeri çekildiğinde, bir konteyner ile iletişim terminal arayüz protokolüne uygun olmalıdır . Bir dize borulama yapmaz.

7

Geç cevap, ama birine yardımcı olabilir

docker run/exec -ikap içindeki komutun STDIN'ini kendi STDIN'ine bağlayacaktır docker run/exec.

Yani

  • docker run -i alpine catgiriş için bekleyen boş bir satır verir. "Merhaba" yazın, yankı "merhaba" elde edersiniz. Ana işlem cat, uçbirim terminali olan sonsuz akıştan girdi beklediğinden , CTRL + D gönderilinceye kadar kap çıkmaz docker run.
  • Öte yandan echo "hello" | docker -i run alpine cat, "merhaba" yazdıracak catve giriş akışının sona erdiğini ve kendini sonlandırdığını bildirdiği için hemen çıkacaktır .

docker psYukarıdakilerden herhangi birinden çıktıktan sonra denerseniz , çalışan kap bulamazsınız. Her iki durumda da, catkendisi sonlandırıldı, böylece liman işçisi konteyneri sonlandırdı.

Şimdi "-t" için, docker içindeki ana işleme girişinin bir terminal cihazı olduğunu söyler.

Yani

  • docker run -t alpine catsize boş bir satır verecektir, ancak "merhaba" yazmaya çalışırsanız yankı almayacaksınız. Bunun nedeni, catbir terminal girişine bağlıyken, bu girişin girişinize bağlı olmamasıdır. Yazdığınız "merhaba" girdisine ulaşmadı cat. cathiç gelmeyen girdileri bekliyor.
  • echo "hello" | docker run -t alpine cat size boş bir satır verecek ve CTRL-D'deki kapsayıcıdan çıkmayacak, ancak geçemediğiniz için yankı "merhaba" alamayacaksınız -i

CTRL + C gönderirseniz kabuğunuzu geri alırsınız, ancak docker psşimdi denerseniz , catkabın hala çalıştığını görürsünüz . Çünkü cathala kapatılmamış bir girdi akışında beklemektedir. -tBirleştirilmeden yalnız başına herhangi bir yararlı kullanım bulamadım -i.

Şimdi -itbirlikte. Bu, kedinin girişinin bir terminal olduğunu söyler ve aynı zamanda bu terminali girişi docker runbir terminal olan bir terminale bağlar . docker run/execkendi girdisinin aslında onu geçmeden önce bir tty olduğundan emin olacaktır cat. Bu nedenle, input device is not a TTYeğer denerseniz bir alırsınız, echo "hello" | docker run -it alpine catçünkü bu durumda, docker runkendisinin girişi önceki yürütme noktasından gelen borudır docker run, çalıştırılan terminal değil

Son olarak, neden geçmek gerekir -teğer -isizin girişi bağlama hile olacaktır catbireyin girdi? Bunun nedeni komutların girdiye bir terminal olması durumunda farklı davranmasıdır. Bu aynı zamanda en iyi örnekle gösterilmiştir

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -psize bir şifre istemi verecektir. Parolayı yazarsanız, karakterler görünür şekilde yazdırılır.
  • docker run -i alpine shsize boş bir satır verecektir. lsÇıktı aldığınız gibi bir komut yazarsanız, ancak komut istemi veya renkli çıktı almazsınız.

Son iki durumda, çünkü bu davranışı elde mysqlsıra sıra shellgirişi maskeleme veya çıkışı boyama gibi tty belirli bir davranışı kullanmak vermedi böylece uçbirimlerden olarak girdi tedavi değildi ve.


4

Tty, bir terminaliniz olduğunu, xterm veya birçok linux komut satırı arayüzünden biri tarafından sağlanacak bir şey olduğunu gösterir. Onunla ilişkili bir klavye ve metin çıkış arayüzü gerekiyor. Bunu istemek için tipik nedenler, renkli metin çıktı desteği, çeşitli tuş kombinasyonlarının (ok tuşları gibi) işlenmesi ve imleci ekranın etrafında hareket ettirebilmesidir.

Örneğinizin gösterdiği gibi bir docker'a bir komut echoverdiğinizde, o boru giriştir ve o borunun bir tty arayüzü yoktur, sadece bir metin akışıdır. Hata mesajının gösterdiği gibi, bununla birlikte bir tty oluşturmaya çalışmak başarısız olur.



Benim için "klavye ve çıkış arayüzü" ile "STDIN / STDOUT" arasında hala bir boşluk var. Açıkçası "imleç konumu" kavramını STDOUT'a uygulayamazsınız, çünkü STDOUT bir ekran değil, bir akıştır. STDOUT'un üstündeki (sanırım) çıkış arayüzü soyutlamasını hangi spesifikasyonlar tanımlar?
Mikhail Vasin

1
Stdin / stdout'un üstünde çalışan bir arayüz. en.wikipedia.org/wiki/POSIX_terminal_interface
BMitch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.