Cosa significa esattamente "il dispositivo di input non è un TTY" nell'output "docker run"?


18

Questo è un comando che funziona:

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

Questo è un comando che risponde con un messaggio di errore:

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

Vorrei capire esattamente cosa succede qui. Non solo "rimuovi -t e verrà corretto".

So che docker runl' -topzione sta per "Allocate a pseudo-TTY", e ho letto panoramiche storiche di ciò che TTY rappresenta , ma non mi ha aiutato a capire che tipo di contratto viene violato qui.


Non è ridondante, la finestra mobile può creare un TTY senza collegarlo. L'output avrebbe caratteri per il colore, ecc., Ma l'output del terminale non verrebbe convogliato nell'input del contenitore. Pertanto, i caratteri digitati verranno messi in coda per il comando successivo eseguito dopo la chiusura del comando docker.
BMitch,

Posso avviare tty nella finestra mobile? Ho alcune app che smettono di funzionare se non eseguo la finestra mobile -t, ma non riesco a modificare il comando di avvio della finestra mobile in produzione. Quindi devo fare in modo che l'app pensi che sia iniziata -t.
mvorisek,

Risposte:


9

Questa risposta mi ha aiutato a avvolgere la testa:

  • per impostazione predefinita (senza né -i-topzioni) un contenitore Docker invia solo il suo output a STDOUT,
  • con l' -iopzione arriva la connessione a STDIN,
  • -tL'opzione estrae un driver di interfaccia terminale , che funziona sopra STDIN / STDOUT. E quando viene inserito un driver del terminale, la comunicazione con un contenitore deve essere conforme al protocollo dell'interfaccia del terminale . Il piping di una stringa no.

7

Risposta in ritardo, ma potrebbe aiutare qualcuno

docker run/exec -icollegherà lo STDIN del comando all'interno del contenitore allo STDIN dello docker run/execstesso.

Così

  • docker run -i alpine catti dà una riga vuota in attesa di input. Digita "ciao" ottieni l'eco "ciao". Il contenitore non verrà chiuso fino a quando non si invia CTRL + D perché il processo principale catè in attesa di input dal flusso infinito che è l'input del terminale di docker run.
  • D'altra parte echo "hello" | docker -i run alpine catstamperà "ciao" e uscirà immediatamente perché catnota che il flusso di input è terminato e termina da solo.

Se si tenta docker psdi uscire da uno dei precedenti, non si troveranno contenitori in esecuzione. In entrambi i casi, catè terminato, quindi la finestra mobile ha terminato il contenitore.

Ora per "-t", questo dice al processo principale all'interno della finestra mobile che il suo input è un dispositivo terminale.

Così

  • docker run -t alpine catti darà una riga vuota, ma se provi a digitare "ciao", non otterrai alcun eco. Questo perché mentre catè collegato a un ingresso terminale, questo ingresso non è collegato al tuo ingresso. Il "ciao" che hai digitato non ha raggiunto l'input di cat. catè in attesa di input che non arrivano mai.
  • echo "hello" | docker run -t alpine cat ti darà anche una riga vuota e non uscirà dal contenitore su CTRL-D ma non otterrai un eco "ciao" perché non hai superato -i

Se si invia CTRL + C, si ottiene indietro la shell, ma se si tenta docker psora, si vede il catcontenitore ancora in esecuzione. Questo perché catè ancora in attesa su un flusso di input che non è mai stato chiuso. Non ho trovato alcun uso utile per il -tsolo senza essere combinato con -i.

Ora, per -itinsieme. Questo dice a cat che il suo input è un terminale e allo stesso tempo collega questo terminale al cui input docker runè un terminale. docker run/execfarà in modo che il proprio input sia in realtà un tty prima di passarlo a cat. Questo è il motivo per cui otterrai un input device is not a TTYse provi echo "hello" | docker run -it alpine catperché in questo caso, l'input di docker runse stesso è il pipe dell'eco precedente e non il terminale in cui docker runviene eseguito

Infine, perché dovresti passare -tse -ifarà il trucco di collegare l'input catall'input? Questo perché i comandi trattano l'input in modo diverso se si tratta di un terminale. Anche questo è meglio illustrato dall'esempio

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -pti darà una richiesta di password. Se si digita la password, i caratteri vengono stampati visibilmente.
  • docker run -i alpine shti darà una riga vuota. Se si digita un comando come se lssi ottenga un output, ma non si riceverà un prompt o un output colorato.

Negli ultimi due casi, si ottiene questo comportamento perché mysqloltre a shellnon trattare l'input come tty e quindi non ha utilizzato un comportamento specifico di tty come mascherare l'input o colorare l'output.


4

Un tty indica che hai un terminale, qualcosa che sarebbe fornito da xterm o da una delle molte interfacce della riga di comando di Linux. Ha bisogno di un'interfaccia di output di tastiera e testo ad esso associata. I motivi tipici per volerlo sono il supporto dell'output del testo a colori, la gestione di varie combinazioni di tasti (come i tasti freccia) e la possibilità di spostare il cursore sullo schermo.

Quando installi un comando nella finestra mobile come echomostra il tuo esempio, quel pipe è l'input e quel pipe non ha un'interfaccia tty, è solo un flusso di testo. Il tentativo di creare un tty con quello fallirà come indica il messaggio di errore.



C'è ancora un divario per me tra "una tastiera e un'interfaccia di output" e "STDIN / STDOUT". Ovviamente non è possibile applicare il concetto di "posizione del cursore" a STDOUT, poiché STDOUT è uno stream, non uno schermo. Quali specifiche descrivono l'astrazione dell'interfaccia di output che (suppongo sia) in cima a STDOUT?
Mikhail Vasin,

1
È un'interfaccia che gira su stdin / stdout. en.wikipedia.org/wiki/POSIX_terminal_interface
BMitch
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.