Błąd „Urządzenie wejściowe nie jest urządzeniem TTY”

425

Korzystam z następującego polecenia z mojego Jenkinsfile. Jednak pojawia się błąd „Urządzenie wejściowe nie jest urządzeniem TTY” .

docker run -v $PWD:/foobar -it cloudfoundry/cflinuxfs2 /foobar/script.sh

Czy istnieje sposób na uruchomienie skryptu z Jenkinsfilepominięciem trybu interaktywnego?

Zasadniczo mam plik o nazwie script.sh, który chciałbym uruchomić w kontenerze Docker.

Anthony
źródło
W przypadku * nix wygląda na to, że nie ma tutaj rozwiązania. „docker exec -i” nie działa, podobnie jak „-t”.
rjurney
1
@rjurney Czy kiedykolwiek znalazłeś rozwiązanie dla docker exec? Próbowałem -i i -t bezskutecznie. docker exec -it mycontainer bash certbot --apache -d www.website.com - mail *********@gmail.com --agree-tos -n
Hutch
@Hutch Niestety, nie pamiętam :(
rjurney

Odpowiedzi:

639

Usuń -itz cli, aby nie było interaktywne i usuń TTY. Jeśli nie potrzebujesz, np. Uruchamiając polecenia w skrypcie Jenkins lub cron, powinieneś to zrobić.

Możesz też zmienić to na, -ijeśli wprowadziłeś potok do polecenia dokera, które nie pochodzi z TTY. Jeśli masz coś podobnego xyz | docker ...lub docker ... <inputw wierszu poleceń, zrób to.

Możesz też zmienić na, -tjeśli chcesz obsługiwać TTY, ale nie masz go na urządzeniu wejściowym. Zrób to, aby sformatować kolory danych wyjściowych w dziennikach lub gdy później przymocujesz do kontenera za pomocą odpowiedniego terminala.

Lub jeśli potrzebujesz terminalu interaktywnego i nie pracujesz w terminalu w systemie Linux lub MacOS, użyj innego interfejsu wiersza polecenia. Zgłoszono, że PowerShell zawiera tę obsługę w systemie Windows.


Co to jest TTY? Jest to interfejs terminala, który obsługuje wyjście kolorów, sekwencje specjalne, przesuwanie kursora itp., Który pochodzi z dawnych czasów głupich terminali podłączonych do komputerów mainframe. Dzisiaj są dostarczane przez terminale poleceń Linux i interfejsy ssh. Aby uzyskać więcej informacji, zobacz artykuł w Wikipedii .

BMitch
źródło
10
Używam tego polecenia w połączeniu z mysql -pbez podawania hasła. Po prostu dodanie -ihasła nigdy nie pojawia się. Po dodaniu -tmonitu pojawia się monit, ale wydaje się, że w ogóle nie odczytuje danych wejściowych (które są drukowane dosłownie, zamiast być ukryte przez monit), nawet po naciśnięciu klawisza return; tylko ctrl-c może to zakończyć. Czy w jakiś sposób można w ten sposób używać klienta mysql z dokerem?
ohcibi
95

Dla tych, którzy zmagają się z tym błędem i git bash w Windows, wystarczy użyć PowerShell, gdzie -itdziała idealnie.

Piotr Justyna
źródło
12
To nie odpowiada na pytanie. Pytanie dotyczy dokera w Jenkins, a nie git bash w systemie Windows.
45
Dobrze. prawda i nigdy nie było to zamierzone. Pytanie pojawia się w Google podczas wyszukiwania tego konkretnego komunikatu o błędzie. Uznałem, że lepiej gdzieś znaleźć odpowiedź, niż w ogóle jej nie mieć. Najwyraźniej niektórzy uznali to za przydatne :)
Piotr Justyna
3
Problem z Powershellem jako TTY dla operacji powłoki polega na tym, że nie przekazuje poprawnie klawiszy strzałek, takich jak strzałka w górę dla historii poleceń cyklicznych. Działa świetnie poza tym brakiem.
Corgalore,
2
Jeśli chcesz nadal korzystać z Git Bash, zapoznaj się z tą odpowiedzią na inne pytanie lub z pustą odpowiedzią poniżej
tessafyi
67

Nie jest to dokładnie to, o co prosisz, ale:

Klawisz -T pomógłby osobom korzystającym z docker-compose exec!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup
obrzęk
źródło
2
dokładnie to, czego szukałem. wiesz dlaczego to działa?
Ulad Kasach
6
Właśnie tego potrzebowałem. Zgodnie z pomocą: -T Wyłącz alokację pseudo-tty. Domyślnie docker-compose exec przydziela TTY.
TS
Dzięki stary. Przeszukuję go pod kątem dokowania-komponowania!
ADyDyka
To zadziałało dla mnie!
rlorenzo
59

Jeśli (podobnie jak ja) używasz git bash w systemie Windows, wystarczy umieścić

winpty

przed „linią dokującą”:

winpty docker exec -it some_cassandra bash
Gremi64
źródło
skąd pobrać winpty?
Mor Shemesh
6
Próbowałeś zanim zapytałeś? Myślę, że pochodzi z Gitem (moja jest w środku ... / Git / usr / bin)
Gremi64
Masz rację, jest poniżejC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh
31

Uważam, że musisz być w TTY, aby doker mógł przydzielić TTY ( -topcja). Jenkins wykonuje swoje zadania nie w TTY.

Powiedziawszy to, skrypt, który uruchamiasz w Jenkins, możesz również chcieć uruchomić lokalnie. W takim przypadku przydzielenie TTY może być bardzo wygodne, aby można było wysyłać sygnały takie jak ctrl+ cpodczas lokalnego uruchamiania.

Aby to naprawić, opcjonalnie użyj skryptu -t:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...
Gareth A. Lloyd
źródło
Ten błąd przytrafił mi się podczas uruchamiania docker run…polecenia z zadania makefile wyzwalanego przez haczyk
Édouard Lopez
1
to powinna być zaakceptowana odpowiedź. faktycznie adresy problemu w sposób powszechnie obowiązującego
roothahn
11

podczas korzystania z „git bash”,

1) Wykonuję polecenie:

docker exec -it 726fe4999627 /bin/bash

Mam błąd:

the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

2) następnie wykonuję polecenie:

winpty docker exec -it 726fe4999627 /bin/bash

Mam inny błąd:

OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"D:/Git/usr/bin/
bash.exe\": stat D:/Git/usr/bin/bash.exe: no such file or directory": unknown

3) po trzecie, wykonuję:

winpty docker exec -it 726fe4999627 bash

zadziałało.

kiedy używam „PowerShell”, wszystko działało dobrze.

wangsir
źródło
Uderzyłem też głową o ścianę przez kilka godzin z tymi problemami przy użyciu bash. Przełączono na PowerShell i wszystko działa teraz!
David Spenard
5

jeśli używasz Windowsa, wypróbuj cmd, dla mnie to działa. sprawdź, czy doker jest uruchomiony.

Diego Santa Cruz Mendezú
źródło
1

winpty działa, o ile nie określisz woluminów do zamontowania, takich jak „.: / mountpoint” lub „$ {pwd}: / mountpoint”

Najlepszym obejściem, jakie znalazłem, jest użycie wtyczki git-bash w Visual Code Studio i użycie terminala do uruchamiania i zatrzymywania kontenerów lub tworzenia dokerów.

Zardzewiały 1
źródło
1

Wiem, że nie jest to bezpośrednia odpowiedź na pytanie, ale dla każdego, kto przyjdzie na to pytanie, kto używa WSL z uruchomionym Dockerem dla Windows i cmder lub conemu.

Sztuką nie jest używanie Dockera, który jest instalowany w systemie Windows w / mnt / c / Program Files / Docker / Docker / resources / bin / docker.exe, ale raczej instalowanie Dockera ubuntu / linux. Warto zauważyć, że nie można uruchomić Dockera bezpośrednio z poziomu WSL, ale można połączyć się z Dockerem dla Windows z klienta Linux Docker.

Zainstaluj Docker w systemie Linux

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce

Połącz się z Dockerem dla Windows na porcie 2375, który należy włączyć w ustawieniach okna dokowanego dla Windows.

docker -H localhost:2375 run -it -v /mnt/c/code:/var/app -w "/var/app" centos:7

Lub ustaw zmienną docker_host, która pozwoli ci pominąć przełącznik -H

export DOCKER_HOST=tcp://localhost:2375

Powinieneś być teraz w stanie łączyć się interaktywnie z sesją terminala tty.

Damo
źródło
0

Mój krok potoku Jenkins pokazany poniżej nie powiódł się z tym samym błędem.

       steps {
            echo 'Building ...' 
            sh 'sh ./Tools/build.sh'
        }

W moim „ build.sh ” skrypt „ run doker ” wyjście polecenia ten błąd, kiedy została ona wykonana przez Jenkins pracy. Jednak działało OK, gdy skrypt działał w terminalu powłoki. Błąd wystąpił z powodu opcji -t przekazanej do komendy uruchamiania dokera, która jak wiem próbuje przydzielić terminal i kończy się niepowodzeniem, jeśli nie ma alokacji terminala.

W moim przypadku zmieniłem skrypt na opcję -t tylko wtedy, gdy można było wykryć terminal. Oto kod po zmianach:

DOCKER_RUN_OPTIONS="-i --rm"

# Only allocate tty if we detect one
if [ -t 0 ] && [ -t 1 ]; then
    DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -t"
fi

docker run $DOCKER_RUN_OPTIONS --name my-container-name  my-image-tag
Namik Hadżijew
źródło