「docker run」輸出中的「輸入裝置不是 TTY」到底代表什麼?

「docker run」輸出中的「輸入裝置不是 TTY」到底代表什麼?

這是一個有效的命令:

$ echo 'hi there' | docker run -i ubuntu cat
hi there

這是一條回應錯誤訊息的命令:

$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY

我想弄清楚這裡究竟發生了什麼事。不僅僅是「刪除-t,它就會被修復」。

我知道docker run's-t選項代表“分配偽 TTY”,並且我已閱讀TTY 代表的歷史概述,但這並沒有幫助我理解這裡違反了什麼樣的合約。

答案1

遲到的回答,但可能對某人有幫助

docker run/exec -i會將容器內指令的 STDIN 連接到其docker run/exec本身的 STDIN。

所以

  • docker run -i alpine cat給你一個空白行等待輸入。輸入“hello”你會得到一個迴聲“hello”。在您發送 CTRL+D 之前,容器不會退出,因為主進程cat正在等待來自無限流的輸入,該無限流是docker run.
  • 另一方面,echo "hello" | docker run -i alpine cat將列印“hello”並立即退出,因為cat注意到輸入流已結束並自行終止。

docker ps如果您在退出上述任一操作後嘗試,您將找不到任何正在運行的容器。在這兩種情況下,cat它本身都已終止,因此 docker 已終止容器。

現在對於“-t”,這告訴docker內部的主進程它的輸入是終端設備。

所以

  • docker run -t alpine cat會給你一個空行,但是如果你嘗試輸入“hello”,你將不會得到任何迴聲。這是因為雖然cat連接到終端輸入,但該輸入未連接到您的輸入。您輸入的「hello」沒有到達 的輸入catcat正在等待永遠不會到達的輸入。
  • echo "hello" | docker run -t alpine cat也會給你一個空行,並且不會在 CTRL-D 上退出容器,但你不會得到回顯“hello”,因為你沒有通過-i

如果您發送 CTRL+C,您會取回 shell,但如果您docker ps現在嘗試,您會看到cat容器仍在運行。這是因為cat仍在等待從未關閉的輸入流。我還沒有發現單獨使用-t而不與 結合使用有任何有用的用途-i

現在,為了-it在一起。這告訴 cat 它的輸入是一個終端,同時將該終端連接到其輸入docker run是一個終端。docker run/exec在將其傳遞給 之前,將確保其自己的輸入實際上是一個 tty cat。這就是為什麼你會得到一個input device is not a TTYif you tryecho "hello" | docker run -it alpine cat因為在這種情況下,它本身的輸入是來自前一個 echo 的管道,而不是執行的docker run終端docker run

最後,為什麼你需要傳遞-tif -iwill 來完成將你的輸入連接到 的輸入的技巧cat?這是因為如果輸入是終端,命令會以不同的方式處理輸入。這也可以透過範例得到最好的說明

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p會給你一個密碼提示。如果您輸入密碼,字元就會清楚列印出來。
  • docker run -i alpine sh會給你一個空白行。如果您鍵入命令,就像您ls得到輸出一樣,但您不會得到提示或彩色輸出。

在最後兩種情況下,您會得到此行為,因為mysql我們shell沒有將輸入視為 tty,因此沒有使用 tty 特定行為,例如屏蔽輸入或為輸出著色。

答案2

這個答案幫助我理清思路:

  • 預設情況下(既沒有-i也沒有-t選項)Docker 容器僅將其輸出傳送至 STDOUT,
  • 帶有-i與 STDIN 的連接選項,
  • -t選項拉入終端介面驅動程式,它在 STDIN/STDOUT 之上工作。當拉入終端驅動程式時,與容器的通訊必須符合終端介面協定。管道化字串則不然。

答案3

tty 表示您有一個終端,它是由 xterm 或眾多 Linux 命令列介面之一提供。它需要一個與之關聯的鍵盤和文字輸出介面。想要這樣做的典型原因是支援彩色文字輸出、處理各種組合鍵(如箭頭鍵)以及在螢幕上移動遊標的能力。

當您像echo範例所示將命令透過管道傳輸到 docker 時,該管道是輸入,且該管道沒有 tty 接口,它只是一個文字流。嘗試使用該命令建立 tty 將失敗,如錯誤訊息所示。

相關內容