Soluzione 1:
Risposta tardiva, ma potrebbe aiutare qualcuno
docker run/exec -i
collegherà lo STDIN del comando all'interno del contenitore allo STDIN del docker run/exec
si.
Quindi
docker run -i alpine cat
ti dà una riga vuota in attesa di input. Digita "ciao" ottieni un eco "ciao". Il contenitore non uscirà fino a quando non invii CTRL+D perché il processo principalecat
è in attesa di input dal flusso infinito che è l'input terminale deldocker run
.- D'altra parte
echo "hello" | docker -i run alpine cat
stamperà "ciao" e uscirà immediatamente perchécat
nota che il flusso di input è terminato e termina da solo.
Se provi docker ps
dopo essere uscito da uno dei precedenti, non troverai alcun contenitore in esecuzione. In entrambi i casi, cat
stesso è terminato, quindi docker ha terminato il contenitore.
Ora per "-t", questo dice al processo principale all'interno della finestra mobile che il suo input è un dispositivo terminale.
Quindi
docker run -t alpine cat
ti darà una riga vuota, ma se provi a digitare "ciao", non otterrai alcun eco. Questo perché mentrecat
è collegato a un ingresso terminale, questo ingresso non è collegato al proprio ingresso. Il "ciao" che hai digitato non ha raggiunto l'input dicat
.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 riceverai un echo "ciao" perché non hai passato-i
Se invii CTRL+C, ti viene restituita la shell, ma se provi docker ps
ora vedi cat
contenitore ancora in funzione. Questo perché cat
è ancora in attesa di un flusso di input che non è mai stato chiuso. Non ho trovato alcun uso utile per il -t
da solo senza essere combinato con -i
.
Ora, per -it
insieme. Questo dice a cat che il suo input è un terminale e allo stesso tempo collega questo terminale all'input di docker run
che è un terminale. docker run/exec
si assicurerà che il proprio input sia effettivamente un tty prima di passarlo a cat
. Questo è il motivo per cui otterrai un input device is not a TTY
se provi echo "hello" | docker run -it alpine cat
perché in questo caso, l'input di docker run
stesso è la pipe dell'eco precedente e non il terminale dove docker run
viene eseguito
Infine, perché dovresti superare -t
se -i
farà il trucco di collegare il tuo input a cat
l'input? Questo perché i comandi trattano l'input in modo diverso se si tratta di un terminale. Questo è anche meglio illustrato dall'esempio
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
ti darà una richiesta di password. Se digiti la password, i caratteri vengono stampati in modo visibile.docker run -i alpine sh
ti darà una riga vuota. Se digiti un comando comels
ottieni un output, ma non otterrai un prompt o un output colorato.
Negli ultimi due casi, ottieni questo comportamento perché mysql
così come shell
non trattavano l'input come un tty e quindi non utilizzavano un comportamento specifico di tty come mascherare l'input o colorare l'output.
Soluzione 2:
Questa risposta mi ha aiutato a capire:
- per impostazione predefinita (senza né
-i
né-t
opzioni) un contenitore Docker invia il suo output solo a STDOUT, - con
-i
opzione arriva la connessione a STDIN, -t
l'opzione inserisce un driver di interfaccia del 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. Piping una stringa non.
Soluzione 3:
Un tty indica che hai un terminale, qualcosa che verrebbe fornito da xterm o da una delle tante interfacce della riga di comando di Linux. Ha bisogno di una tastiera e di un'interfaccia di output di testo ad essa associati. 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 inserisci un comando nella finestra mobile come il tuo echo
esempio mostra, quella pipe è l'input e quella 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.