Lỗi Thiết bị đầu vào không phải là TTY


425

Tôi đang chạy lệnh sau từ của tôi Jenkinsfile. Tuy nhiên, tôi gặp lỗi "Thiết bị đầu vào không phải là TTY" .

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

Có cách nào để chạy tập lệnh từ Jenkinsfilemà không thực hiện chế độ tương tác không?

Về cơ bản tôi có một tệp được gọi là script.shtôi muốn chạy bên trong container Docker.


Đối với * nix, có vẻ như không có giải pháp nào ở đây. 'Docker exec -i' không hoạt động, cũng không '-t'.
rjurney

1
@rjurney Bạn đã bao giờ tìm thấy một giải pháp cho docker exec chưa? Tôi đã thử -i và -t không thành công. docker exec -it mycontainer bash certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch

@Hutch Xin lỗi, tôi không thể nhớ :(
rjurney

Câu trả lời:


639

Xóa -itkhỏi cli của bạn để làm cho nó không tương tác và xóa TTY. Nếu bạn không cần, ví dụ: chạy lệnh của bạn bên trong tập lệnh Jenkins hoặc cron, bạn nên làm điều này.

Hoặc bạn có thể thay đổi nó thành -inếu bạn đã nhập vào lệnh docker không xuất phát từ TTY. Nếu bạn có một cái gì đó như xyz | docker ...hoặc docker ... <inputtrong dòng lệnh của bạn, hãy làm điều này.

Hoặc bạn có thể thay đổi thành -tnếu bạn muốn hỗ trợ TTY nhưng không có sẵn trên thiết bị đầu vào. Làm điều này để định dạng màu của đầu ra trong nhật ký của bạn hoặc sau này khi bạn gắn vào thùng chứa với một thiết bị đầu cuối thích hợp.

Hoặc nếu bạn cần một thiết bị đầu cuối tương tác và không chạy trong thiết bị đầu cuối trên Linux hoặc MacOS, hãy sử dụng giao diện dòng lệnh khác. PowerShell được báo cáo là bao gồm hỗ trợ này trên Windows.


TTY là gì? Đó là một giao diện đầu cuối hỗ trợ đầu ra màu, các chuỗi thoát, di chuyển con trỏ xung quanh, v.v., xuất phát từ ngày xưa của các thiết bị đầu cuối câm gắn liền với máy tính lớn. Ngày nay, nó được cung cấp bởi các thiết bị đầu cuối lệnh Linux và giao diện ssh. Xem bài viết trên wikipedia để biết thêm chi tiết .


10
Tôi đang sử dụng lệnh này kết hợp với mysql -pmà không chỉ định mật khẩu. Khi chỉ cần thêm -idấu nhắc mật khẩu không bao giờ xuất hiện. Chỉ cần thêm -tdấu nhắc xuất hiện nhưng dường như nó không đọc đầu vào (được in theo nghĩa đen thay vì bị ẩn bởi dấu nhắc), ngay cả khi nhấn return; chỉ ctrl-c có thể kết thúc nó. Có cách nào đó có thể sử dụng máy khách mysql với docker theo cách đó không?
ohcibi

95

Đối với những người đấu tranh với lỗi này và git bash trên Windows, chỉ cần sử dụng PowerShell nơi -ithoạt động hoàn hảo.


12
Điều này không trả lời câu hỏi. Câu hỏi là về docker trong Jenkins, không phải git bash trên Windows.

45
Tốt. đúng, và nó không bao giờ có ý định. Câu hỏi bật lên trong google khi bạn tìm kiếm thông báo lỗi cụ thể này. Tôi hình dung, tốt hơn là có câu trả lời ở đâu đó hơn là không có nó. Rõ ràng một số người thấy nó hữu ích :)
Piotr Justyna

3
Vấn đề với Powershell là TTY cho các thao tác shell là nó không chuyển đúng các phím mũi tên, giống như mũi tên lên cho lịch sử lệnh đi xe đạp. Hoạt động tuyệt vời khác hơn là thiếu sót.
Corgalore

2
Nếu bạn muốn tiếp tục sử dụng Git Bash, hãy xem câu trả lời này cho một câu hỏi khác hoặc câu trả lời winpty bên dưới
tessafyi

68

Đó không phải là chính xác những gì bạn đang hỏi, nhưng:

Các chính -T sẽ giúp những người đang sử dụng Docker-soạn exec!

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

2
Chính xác những gì tôi đang tìm kiếm. Bạn có biết tại sao điều này làm việc?
Ulad Kasach

6
Chỉ cần những gì tôi cần quá. Theo sự giúp đỡ: -T Vô hiệu hóa phân bổ giả. Theo mặc định docker-compose exec phân bổ một TTY.
TS

Cảm ơn người đàn ông. Tôi tìm kiếm nó cho docker-compose!
ADyDyka

Điều này làm việc cho tôi!
rlorenzo

59

Nếu bạn (như tôi) sử dụng git bash trên windows, bạn chỉ cần đặt

thắng

trước line dòng docker 'của bạn:

winpty docker exec -it some_cassandra bash

Làm thế nào để bạn tải về winpty?
Mor Shemesh

6
Bạn đã thử trước khi hỏi? Tôi nghĩ rằng nó đi kèm với Git (của tôi ở bên trong ... / Git / usr / bin)
Gremi64

Bạn nói đúng, nó ở dướiC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh

31

Tôi tin rằng bạn cần phải ở trong TTY cho docker để có thể phân bổ TTY ( -ttùy chọn). Jenkins thực hiện công việc của mình không trong TTY.

Phải nói rằng, kịch bản bạn đang chạy trong Jenkins bạn cũng có thể muốn chạy cục bộ. Trong trường hợp đó, có thể thực sự thuận tiện khi có TTY được phân bổ để bạn có thể gửi tín hiệu như ctrl+ ckhi chạy cục bộ.

Để khắc phục điều này, làm cho tập lệnh của bạn tùy ý sử dụng -ttùy chọn, như vậy:

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

Lỗi này xảy ra với tôi khi chạy docker run…lệnh tạo một tác vụ makefile được kích hoạt bởi hook git
Édouard Lopez

1
đây sẽ là câu trả lời được chấp nhận nó thực sự giải quyết vấn đề theo cách áp dụng phổ biến
roothahn

11

khi sử dụng 'git bash',

1) Tôi thực hiện lệnh:

docker exec -it 726fe4999627 /bin/bash

Tôi có lỗi:

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

2) sau đó, tôi thực hiện lệnh:

winpty docker exec -it 726fe4999627 /bin/bash

Tôi có một lỗi khác:

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) thứ ba, tôi thực hiện:

winpty docker exec -it 726fe4999627 bash

nó đã làm việc.

Khi tôi sử dụng 'powershell', tất cả đều hoạt động tốt.


Gục đầu vào tường, trong vài giờ với những vấn đề này bằng cách sử dụng bash. Chuyển sang Powershell và tất cả các công trình bây giờ!
David Spenard

5

Nếu sử dụng windows, hãy thử với cmd, đối với tôi nó hoạt động. kiểm tra nếu docker được bắt đầu.


1

winpty hoạt động miễn là bạn không chỉ định khối lượng được gắn kết, chẳng hạn như ".: / mountpoint" hoặc "$ {pwd}: / mountpoint"

Cách giải quyết tốt nhất mà tôi đã tìm thấy là sử dụng plugin git-bash bên trong Visual Code Studio và sử dụng thiết bị đầu cuối để bắt đầu và dừng các container hoặc soạn thảo docker.


1

Tôi biết điều này không trực tiếp trả lời câu hỏi mà cho bất kỳ ai gặp phải câu hỏi này, người đang sử dụng WSL chạy Docker cho windows và cmder hoặc conemu.

Thủ thuật không phải là sử dụng Docker được cài đặt trên windows tại / mnt / c / Chương trình tập tin / Docker / Docker / resource / bin / docker.exe mà là để cài đặt Docker ubfox / linux. Thật đáng để chỉ ra rằng bạn không thể tự chạy Docker từ bên trong WSL nhưng bạn có thể kết nối với Docker cho các cửa sổ từ máy khách Docker linux.

Cài đặt Docker trên 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

Kết nối với Docker cho các cửa sổ trên cổng 2375 cần được bật từ cài đặt trong docker cho windows.

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

Hoặc đặt biến docker_host sẽ cho phép bạn bỏ qua công tắc -H

export DOCKER_HOST=tcp://localhost:2375

Bây giờ bạn có thể kết nối tương tác với một phiên thiết bị đầu cuối tty.


0

Bước đường ống Jenkins của tôi hiển thị bên dưới không thành công với cùng một lỗi.

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

Trong tập lệnh " build.sh " của tôi, lệnh " docker run " xuất ra lỗi này khi nó được thực thi bởi công việc Jenkins. Tuy nhiên nó vẫn hoạt động tốt khi tập lệnh chạy trong thiết bị đầu cuối shell. Lỗi xảy ra do tùy chọn -t được truyền cho lệnh chạy docker mà như tôi biết đã cố gắng phân bổ thiết bị đầu cuối và không thành công nếu không có thiết bị đầu cuối để phân bổ.

Trong trường hợp của tôi, tôi đã thay đổi tập lệnh thành tùy chọn -t chỉ khi thiết bị đầu cuối có thể được phát hiện. Đây là mã sau khi thay đổi:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.