「入力デバイスはTTYではありません」とは、「ドッカー実行」の出力ではどういう意味ですか?


18

これは機能するコマンドです:

$ 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-tオプションは「擬似TTYを割り当てる」の略でありTTYの略の歴史的な概要を読んだことがありますが、ここではどのような契約に違反しているかを理解する助けにはなりませんでした。


冗長ではありません。Dockerは何もアタッチせずにTTYを作成できます。出力には色などの文字が含まれますが、ターミナル出力はコンテナの入力にパイプされません。したがって、入力した文字は、dockerコマンドの終了後に実行する次のコマンドのキューに入れられます。
BMitch

Docker内でttyを起動できますか?でドッカーを実行しないと-t、動作を停止するアプリがいくつかありますが、実稼働環境ではドッカー開始コマンドを変更できません。だから私はアプリにそれが始まったと思わせる必要があります-t
mvorisek

回答:


9

この答えは、私の頭を包むのに役立ちました:

  • デフォルトでは(オプション-iもなし-t)、Dockerコンテナーはその出力をSTDOUTにのみ送信します。
  • -iオプションSTDINへの接続が来て、
  • -tオプションは、 STDIN / STDOUTの上で動作するターミナルインターフェイスドライバーを取り込みます。そして、ターミナルドライバーが引き込まれると、コンテナとの通信はターミナルインターフェイスプロトコルに準拠する必要があります。文字列のパイプはしません。

7

遅い答えですが、誰かを助けるかもしれません

docker run/exec -iコンテナ内のコマンドのSTDINをdocker run/execそれ自体のSTDINに接続します。

そう

  • docker run -i alpine cat入力を待っている空の行を提供します。「hello」と入力すると、エコー「hello」が表示されます。メインプロセスcatがの端末入力である無限ストリームからの入力を待機しているため、CTRL + Dを送信するまでコンテナは終了しませんdocker run
  • 一方、入力ストリームが終了し、それ自体が終了したecho "hello" | docker -i run alpine catことにcat気付くため、「hello」を出力してすぐに終了します。

docker ps上記のいずれかを終了した後に試しても、実行中のコンテナは見つかりません。どちらの場合も、catそれ自体が終了したため、dockerはコンテナを終了しました。

「-t」の場合、これは入力が端末デバイスであることをdocker内のメインプロセスに伝えます。

そう

  • docker run -t alpine cat空の行が表示されますが、「hello」と入力しても、エコーは表示されません。これはcat、端末入力に接続されている間、この入力は入力に接続されていないためです。入力した「ハロー」はの入力に達しませんでしたcatcat到着しない入力を待っています。
  • echo "hello" | docker run -t alpine cat また、空の行を提供し、CTRL-Dでコンテナを終了しませんが、パスしなかったためエコー「hello」を取得しません -i

CTRL + Cを送信すると、シェルが返されますが、docker ps今すぐ試してみると、catコンテナーがまだ実行されていることがわかります。これは、cat閉じられなかった入力ストリームをまだ待機しているためです。と-t組み合わせずに単独での有用な使用を発見していません-i

今、-it一緒に。これは、その入力が端末であると同時に、この端末を端末である入力に接続することをcatに伝えdocker runます。docker run/execに渡す前に、それ自身の入力が実際にttyであることを確認しcatます。これは、この場合、それ自体の入力が前のエコーからのパイプであり、実行される端末ではないため、input device is not a TTY試してみると取得される理由ですecho "hello" | docker run -it alpine catdocker rundocker run

最後に、入力をの入力に接続するトリックを実行する-t場合、なぜ合格する必要がありますか?これは、端末の場合、コマンドは入力を異なる方法で処理するためです。これは、例によって最もよく説明されています-icat

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -pパスワードプロンプトが表示されます。パスワードを入力すると、文字が表示されます。
  • docker run -i alpine sh空の行が表示されます。ls出力を取得するようなコマンドを入力しても、プロンプトまたは色付きの出力は表示されません。

最後の2つのケースでは、この動作を得るmysqlだけでなく、としてshellの入力をマスキングまたは出力を着色するようにttyの特定の動作を使用していなかったので、ttyのように、入力を処理していなかったと。


4

ttyは、xtermまたは多くのLinuxコマンドラインインターフェイスのいずれかによって提供される端末があることを示します。キーボードとそれに関連付けられたテキスト出力インターフェイスが必要です。これが必要な一般的な理由は、カラーテキスト出力のサポート、さまざまなキーの組み合わせ(矢印キーなど)の処理、およびカーソルを画面上で移動できるためです。

echo例のようにコマンドをdockerにパイプすると、そのパイプが入力になり、そのパイプにはttyインターフェイスがありません。これは単なるテキストのストリームです。エラーメッセージが示すように、それを使用してttyを作成しようとすると失敗します。



「キーボードと出力インターフェイス」と「STDIN / STDOUT」の間にはまだギャップがあります。STDOUTは画面ではなくストリームであるため、明らかに「カーソル位置」の概念をSTDOUTに適用することはできません。STDOUTの上にある(と思われる)出力インターフェイスの抽象化を記述する仕様は何ですか?
ミハイルヴァ

1
これは、stdin / stdoutの上で実行されるインターフェースです。en.wikipedia.org/wiki/POSIX_terminal_interface
BMitch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.