Kesalahan “Perangkat input bukan TTY”


425

Saya menjalankan perintah berikut dari Jenkinsfile. Namun, saya mendapatkan kesalahan "Perangkat input bukan TTY" .

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

Apakah ada cara untuk menjalankan skrip dari Jenkinsfiletanpa melakukan mode interaktif?

Saya pada dasarnya memiliki file bernama script.shyang ingin saya jalankan di dalam wadah Docker.


Untuk * nix, sepertinya tidak ada solusi di sini. 'buruh pelabuhan exec -i' tidak bekerja, juga tidak '-t'.
rjurney

1
@ rjurney Apakah Anda pernah menemukan solusi untuk docker exec? Saya telah mencoba -i dan -t tanpa hasil. buruh pelabuhan exec-it mycontainer bash certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch

@Hutch Maaf, saya tidak ingat :(
rjurney

Jawaban:


639

Hapus -itdari cli Anda untuk membuatnya tidak interaktif dan hapus TTY. Jika Anda tidak perlu, misalnya menjalankan perintah di dalam Jenkins atau skrip cron, Anda harus melakukan ini.

Atau Anda dapat mengubahnya menjadi -ijika Anda memiliki input yang disalurkan ke perintah buruh pelabuhan yang tidak berasal dari TTY. Jika Anda memiliki sesuatu seperti xyz | docker ...atau docker ... <inputdi baris perintah Anda, lakukan ini.

Atau Anda dapat mengubahnya -tjika Anda menginginkan dukungan TTY tetapi tidak tersedia di perangkat input. Lakukan ini untuk memformat warna output dalam log Anda, atau ketika Anda nanti menempelkan wadah dengan terminal yang tepat.

Atau jika Anda memerlukan terminal interaktif dan tidak berjalan di terminal di Linux atau MacOS, gunakan antarmuka baris perintah yang berbeda. PowerShell dilaporkan menyertakan dukungan ini pada Windows.


Apa itu TTY? Ini adalah antarmuka terminal yang mendukung output warna, urutan keluar, memindahkan kursor, dll, yang berasal dari masa lalu terminal bodoh yang melekat pada mainframe. Hari ini disediakan oleh terminal perintah Linux dan antarmuka ssh. Lihat artikel wikipedia untuk lebih jelasnya .


10
Saya menggunakan perintah ini bersamaan dengan mysql -ptanpa menentukan kata sandi. Saat menambahkan -iprompt kata sandi tidak pernah muncul. Dengan hanya menambahkan -tprompt muncul tetapi tampaknya tidak membaca input (yang dicetak secara harfiah alih-alih disembunyikan oleh prompt) sama sekali, bahkan ketika memukul kembali; hanya ctrl-c yang bisa mengakhirinya. Apakah mungkin menggunakan klien mysql dengan buruh pelabuhan seperti itu?
ohcibi

95

Bagi mereka yang berjuang dengan kesalahan ini dan git bash di Windows, cukup gunakan PowerShell di mana -itberfungsi dengan sempurna.


12
Ini tidak menjawab pertanyaan. Pertanyaannya adalah tentang buruh pelabuhan di Jenkins, bukan git bash di Windows.

45
Baik. benar, dan itu tidak pernah dimaksudkan untuk itu. Pertanyaan muncul di google ketika Anda mencari pesan kesalahan khusus ini. Saya pikir, lebih baik memiliki jawabannya di suatu tempat daripada tidak memilikinya sama sekali. Jelas beberapa orang menganggapnya berguna :)
Piotr Justyna

3
Masalah dengan Powershell sebagai TTY untuk operasi shell adalah bahwa ia tidak benar melewati tombol panah, seperti panah atas untuk sejarah perintah bersepeda. Bekerja sangat baik selain dari kekurangan itu.
Corgalore

2
Jika Anda ingin terus menggunakan Git Bash, lihat jawaban ini pada pertanyaan lain atau jawaban winpty di bawah ini
tessafyi

68

Bukan itu yang Anda tanyakan, tetapi:

The key -T akan membantu orang-orang yang menggunakan buruh pelabuhan-compose exec!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup

2
persis apa yang saya cari. apakah kamu tahu mengapa ini bekerja?
Ulad Kasach

6
Apa yang saya butuhkan juga. Menurut bantuan: -T Nonaktifkan alokasi pseudo-tty. Secara default docker-compose exec mengalokasikan TTY.
TS

Terima kasih sobat. Saya mencarinya untuk menulis-buruh pelabuhan!
ADyDyka

Ini berhasil untuk saya!
rlorenzo

59

Jika Anda (seperti saya) menggunakan git bash di windows, Anda hanya perlu meletakkannya

winpty

sebelum 'docker line' Anda:

winpty docker exec -it some_cassandra bash

Bagaimana cara Anda mengunduh winpty?
Mor Shemesh

6
Apakah Anda sudah mencoba sebelum bertanya? Saya pikir itu datang dengan Git (milik saya di dalam ... / Git / usr / bin)
Gremi64

Anda benar, itu di bawahC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh

31

Saya percaya Anda harus berada dalam TTY untuk buruh pelabuhan agar dapat mengalokasikan TTY ( -topsi). Jenkins menjalankan tugasnya bukan di TTY.

Karena itu, skrip yang Anda jalankan dalam Jenkins Anda mungkin juga ingin dijalankan secara lokal. Dalam hal ini, akan sangat nyaman untuk memiliki alokasi TTY sehingga Anda dapat mengirim sinyal seperti ctrl+ cketika menjalankannya secara lokal.

Untuk memperbaikinya, buat skrip Anda menggunakan -topsi secara opsional , seperti:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...

Kesalahan ini terjadi pada saya ketika menjalankan docker run…perintah dari tugas makefile yang dipicu oleh git hook
Édouard Lopez

1
ini harus menjadi jawaban yang diterima. itu sebenarnya mengatasi masalah dengan cara yang berlaku universal
roothahn

11

saat menggunakan 'git bash',

1) Saya menjalankan perintah:

docker exec -it 726fe4999627 /bin/bash

Saya memiliki kesalahan:

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

2) lalu, saya menjalankan perintah:

winpty docker exec -it 726fe4999627 /bin/bash

Saya memiliki kesalahan lain:

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) ketiga, saya menjalankan:

winpty docker exec -it 726fe4999627 bash

itu berhasil.

ketika saya menggunakan 'PowerShell', semuanya bekerja dengan baik.


Membenturkan kepalaku ke dinding, juga, selama beberapa jam dengan masalah ini menggunakan bash. Beralih ke Powershell dan semua berfungsi sekarang!
David Spenard


1

winpty berfungsi selama Anda tidak menentukan volume yang akan dipasang seperti ".: / mountpoint" atau "$ {pwd}: / mountpoint"

Solusi terbaik yang saya temukan adalah menggunakan plugin git-bash di dalam Visual Code Studio dan menggunakan terminal untuk memulai dan menghentikan kontainer atau membuat docker-compose.


1

Saya tahu ini bukan langsung menjawab pertanyaan yang ada tetapi untuk siapa pun yang datang pada pertanyaan ini yang menggunakan WSL menjalankan Docker untuk windows dan cmder atau conemu.

Caranya bukan dengan menggunakan Docker yang diinstal pada windows di / mnt / c / Program Files / Docker / Docker / resources / bin / docker.exe tetapi untuk menginstal ubuntu / linux Docker. Perlu ditunjukkan bahwa Anda tidak dapat menjalankan Docker sendiri dari dalam WSL tetapi Anda dapat terhubung ke Docker untuk windows dari klien Docker linux.

Instal Docker di 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

Hubungkan ke Docker untuk windows di port 2375 yang perlu diaktifkan dari pengaturan di docker untuk windows.

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

Atau atur variabel docker_host yang memungkinkan Anda menghilangkan -H switch

export DOCKER_HOST=tcp://localhost:2375

Anda sekarang harus dapat terhubung secara interaktif dengan sesi terminal tty.


0

Langkah pipa Jenkins saya yang ditunjukkan di bawah gagal dengan kesalahan yang sama.

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

Dalam skrip " build.sh " file " docker run " saya menampilkan kesalahan ini ketika dieksekusi oleh pekerjaan Jenkins. Namun itu berfungsi dengan baik ketika skrip dijalankan di terminal shell. Kesalahan terjadi karena opsi -t dilewatkan ke perintah run docker yang saya tahu mencoba mengalokasikan terminal dan gagal jika tidak ada terminal untuk mengalokasikan.

Dalam kasus saya, saya telah mengubah skrip menjadi opsi pass -t hanya jika terminal dapat dideteksi. Berikut adalah kode setelah perubahan:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.