「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-tオプションは「疑似TTYを割り当てる」という意味だと知っています。TTY の歴史的概要しかし、ここでどのような契約違反が起こっているのか理解するのに役立ちませんでした。

答え1

遅い回答ですが、誰かの役に立つかもしれません

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

それで

  • docker run -i alpine cat入力を待つ空行が表示されます。「hello」と入力すると、「hello」というエコーが表示されます。メイン プロセスは、のターミナル入力である無限ストリームからの入力を待機しているため、CTRL+D を送信するまでコンテナーは終了しませんcatdocker run
  • 一方、入力ストリームが終了したことを検知して自身を終了するecho "hello" | docker run -i alpine catため、「hello」を出力してすぐに終了します。cat

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

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

それで

  • docker run -t alpine catは空行を表示しますが、「hello」と入力してもエコーは表示されません。これは、 がcat端末入力に接続されているのに対し、この入力はユーザーの入力に接続されていないためです。入力した「hello」は の入力に到達しませんでしたcatcatは、決して到着しない入力を待機しています。
  • echo "hello" | docker run -t alpine cat空の行も表示され、CTRL-Dでコンテナから抜け出すことはできませんが、渡していないため、echo "hello"は表示されません。-i

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

さて、 を-it一緒にします。これは cat にその入力が端末であることを伝え、同時にこの端末を の入力でdocker runある端末に接続します。 は、docker run/execそれを に渡す前に、自身の入力が実際に tty であることを確認します。この場合、 の入力は前の echo からのパイプであり、が実行される端末ではないため、を試みると が返されるのはcatそのためです。input device is not a TTYecho "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 つのケースでは、入力を tty として処理しなかったmysqlため、入力のマスクや出力の色付けなどの tty 固有の動作を使用しなかったために、この動作が発生します。shell

答え2

この答え理解するのに役立ちました:

  • デフォルトでは(オプション-iも指定しない場合-t)、Dockerコンテナは出力をSTDOUTにのみ送信します。
  • オプションで-iSTDINに接続できます。
  • -tオプションは端末インターフェースドライバをプルします、STDIN/STDOUT上で動作する。ターミナルドライバがプルインされると、コンテナとの通信は端末インターフェースプロトコル文字列をパイプすることはそうではありません。

答え3

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

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

関連情報