Docker -t sahte-TTY tahsis seçeneği hakkında karıştı


212

Bu seçenek tam olarak ne yapıyor? TTY hakkında çok şey okudum ve hala kafam karıştı. Ben -tve sadece sahip -iolmadan oynadı ve kullanıcı girişi olmadan bir hata atmak bekliyoruz programlar gibi görünüyor -t. Sahte TTY'nin etkinleştirilmesi neden önemlidir?

Yanıtlar:


228

Bu -tseçenek Unix / Linux'un terminal erişimini nasıl ele aldığını gösterir. Geçmişte bir terminal, daha sonra modem tabanlı bir bağlantı olan bir hardline bağlantıydı. Bunların fiziksel aygıt sürücüleri vardı (gerçek ekipman parçalarıydı). Genelleştirilmiş ağlar kullanıma girdikten sonra, sözde terminal sürücüsü geliştirildi. Bunun nedeni, programınıza doğrudan yazmanıza gerek kalmadan hangi terminal yeteneklerinin kullanılabileceğini anlama arasında bir ayrım yaratmasıdır (man sayfalarını okuyun stty, curses).

Yani, bununla birlikte, arka plan olarak, seçenekleri olmayan bir kapsayıcı çalıştırın ve varsayılan olarak bir stdout akışınız var (böylece docker run | <cmd>çalışır); ile çalıştırın -ive stdin akışı eklendi (böylece <cmd> | docker run -içalışır); kullanmak -tgenellikle bir arada, -itve size işlemiyle etkileşimde eğer eklenen bir terminal sürücü, ne istediğinizi muhtemelen var. Temel olarak, kabın bir terminal bağlantı oturumu gibi görünmesini sağlar.


7
Bu en iyi cevap olmalı. Burada en teknik olanı olmasa da, -itbayrakların temel davranışlarını açıklıyor .
Kris Khaira

1
Kris ile aynı fikirde. Diğer cevapları okudum ve hala tamamen karışmıştım. Bu cevap onu temizler.
Ben Lee

4
Evet, belki de "TTY" nin kendisinin, metin yazmanıza ve aynı anda göndermenize izin veren bir cihaz adı olan "teletypewriter" (AKA "teleprinter") kelimesinden gelen bir kısaltma olduğunu belirtmeye değer. Metin için ;-) Deneyin docker run -i ubuntuve docker run -it ubuntufarkı hemen göreceksiniz. "-i", konteynerin ana bilgisayardan etkileşimi beklemesini sağlar ancak "t" sürücüsünü "-t" ile "tty sürücüsünü ayırdıktan sonra" konsoldan (terminal) gerçek etkileşim mümkündür.
Zegar

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

99

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. Gönderdiğiniz kadar konteyner çıkmayacaktır CTRL+ Dana süreç nedeniyle catterminal girdidir sonsuz akışından girişi bekliyor docker run.
  • Öte yandan echo "hello" | docker run -i 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 catsize boş bir satır verecek ve kaptan çıkmayacak CTRL- Dama yankı "merhaba" almayacaksınız çünkü geçmediniz-i

Eğer gönderirseniz CTRL+ C, size kabuk geri almak, ama eğer deneyin docker psşimdi, gördüğünüz catkonteyner hala çalışıyor. Çü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 -u root -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.


6
Buradaki en iyi cevap, tam olarak ne olduğunu -tve -iseçeneklerin ne yaptığını anlamamı sağlıyor !
Ruslan Stelmachenko

1
Sahip olduğum her soruyu tahmin eden harika cevap
James Machin

@Ahmed Ghonim, Çok iyi cevaplar. Teşekkür ederim. Ama "Bu bir terminal ise komutları girdiye farklı davranması nedeniyle" diye düşünüyorum, bence bu yanlış bir şey, değil mi? "Bu eğer komutları farklı giriş tedavi olmasıdır Öyle olmalı değil doğru bir terminal"?
tuq

@Ahmed Ghonim. Kristal berraklığı. Peki ya docker run -a = stdin alp kedisi ne olacak?
HKIT

1
@HKIIT "-a = stdin" konteynere stdin akışını ekler, ancak bellek ayırması olmadan. Bu, stdin akışı için kapta tampon belleği ayıran -i bayrağıdır, bu nedenle "STDIN açık olmasa bile STDIN'i açık tut" açıklaması, -i geçirildiğinde ek bayraklarına bakılmaksızın stdin için bellek ayrılır. Bu ayrılmış bellek olmadan stdin okumaları boş / eof. Ayrıca cat komutunun yanıtını görmek için "-a = stdout" ifadesini eklemeniz gerekir: "docker run -i -a = stdin -a = stdout alp kedisi" ... tabii ki bunu yapmanıza gerek yok sadece "docker run -i Alp kedisi" çalıştırın.
David D

72

-tArgümanı bir Google arama göre, genellikle birçok kişi tarafından iyi belgelenmiş veya söz DEĞİLDİR.

dockerBash komut istemine (1.8.1'in en son sürümüyle) yazarak tüm docker istemci argümanlarının bir listesini (ne olması gerektiğini) görüntülediğinizde bile görünmez .

Aslında, docker -t --helpbu şaşırtıcı belirsiz yanıtı verirse , yazarak bu argüman hakkında özel yardım almaya çalışırsanız :

bayrak sağlandı ancak tanımlanmadı: -t

Yani, bu argüman hakkında kafanız karıştığı için suçlanamazsınız!

Docker çevrimiçi belgelerinde "Sözde bir atama" yapmak olduğunu ve genellikle aşağıdakilerle birlikte kullanıldığını belirten bir söz vardır -i:

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

Müthiş jwilder/nginx-proxydocker konteyneri için belgelerde aşağıdaki şekilde kullanıldığını gördüm :

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

Bu durumda, çıktıyı bu docker konteyneri içindeki 'sanal' tty'ye (Bash komut istemi / terminali) gönderir. Daha sonra liman işçisi komutunu çalıştırarak bu çıktıyı görebilirsiniz bu kabın kimliği karakterlerin ilk çift. Bu KONTEYNER KİMLİĞİ yazarak bulunabilirdocker logs CONTAINERCONTAINERdocker ps -a

Bu -targümanın kısaca bahsettiğini aşağıdaki linkte gördüm , burada

-tVe -ibayraklar sahte tty tahsis ve bağlı değil bile açık stdin'i tutun. Bu, bash istemi çalıştığı sürece kapsayıcıyı geleneksel bir VM gibi kullanmanıza izin verecektir.

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

Umarım bu yardımcı olur! Bunun neden belgelenmediğinden veya fazla kullanılmadığından emin değilim. Belki deneyseldir ve gelecek sürümlerde belgelenmiş bir özellik olarak uygulanacaktır.


21
İçin dokümantasyon gösterileri docker run --helpdeğil, docker -t --help: -t, --tty=false Allocate a pseudo-TTY"
bskaggs

5

Hakkında bildiklerim -tşudur:

docker exec -ti CONTAINER bash- kapta "giriş" yapmamı sağlar. Ssh-ing gibi geliyor (değil).

Ama sorun bir veritabanını geri yüklemek istediğim zamandı.

Genellikle yapıyorum docker exec -ti mysql.5.7 mysql- Burada kapsayıcıda mysql komutunu yürütmek ve etkileşimli bir terminal almak.

<dump.sqlÖnceki komuta ekledim , böylece bir db'yi geri yükleyebilirim. Ama başarısız oldu cannot enable tty mode on non tty input.

Yardımın kaldırılması -t. Hala nedenini anlamıyorum:

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

Sonuncusu çalışıyor. Umarım bu insanlara yardım eder.


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

1

Linux'ta bir komutu çalıştırdığınızda, yürütmek için bir terminal (tty) gerekir.

Bu nedenle, docker'a bağlanmak istediğinizde (veya docker konteynerinde komutu çalıştırdığınızda), docker konteynerinin içindeki terminali dikkate alan -t seçeneğini sağlamanız gerekir.


0

Her işlemin üç veri akışı vardır STDIN/ STDOUT/ STDERR. Bir işlem bir kapta çalışırken, varsayılan olarak terminal kapta çalışan işlemin STDOUT akışına bağlanır. Bu nedenle docker runterminalde komut çalıştırılırken tüm çıkış akışları görünür olacaktır . Ancak, kapsayıcıda çalışan işleme girdi sağlamak istiyorsanız, işlemin varsayılan olarak olmayan ve docker run -ikomutla yapılan STDIN kanalına bağlanmanız gerekir .

-t etkileşimli / biçimlendirilmiş giriş işlemleri için kullanılır.


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.