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 catti 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 catstamperà "ciao" e uscirà immediatamente perchécatnota 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 catti 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 catti 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 -pti darà una richiesta di password. Se digiti la password, i caratteri vengono stampati in modo visibile.docker run -i alpine shti darà una riga vuota. Se digiti un comando comelsottieni 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é
-iné-topzioni) un contenitore Docker invia il suo output solo a STDOUT, - con
-iopzione arriva la connessione a STDIN, -tl'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.