次の動作を変更する方法を知りたいです。私の端末に28行があるとしましょう。次に、次のコマンドを使用します。
$ tput lines # my terminal
28
$ docker run --rm -it ubuntu:16.04 tput lines # docker container
24 ## WHY??
$ docker run --rm -it ubuntu:16.04 bash # docker container inside command
root@810effa2777c:/# tput lines
28
ご覧のとおり、すべての結果が28であるべき場合でも、docker run --rm -it ubuntu:16.04 tput lines
としてコンテナを呼び出すと、常に24私の端末のサイズにもかかわらず。これは、ubuntuコンテナだけでなく、debian(docker run --rm -it debian tput lines
)でも試しましたが、同じ結果が得られています24。
これの目的は、ターミナルの行を考慮に入れる mdp presentation tool を使用することです。実装が失敗したとき、他の人の docker implementation を試しましたが、同じエラーが発生しました。
これが画像のエラーです。
誰がそれが何であり、どのようにこれを解決できるのか考えていますか?
2018年9月の更新:docker 18.06に同じ問題があるかどうかを確認します( not should 、後に moby/moby
issue 33794 、および moby/moby
issue 35407 および PR 37172 、 18.06リリースノート )の一部。
2016年:
buntu Dockerfile に含まれるもの:
CMD ["/bin/bash"]
つまり、デフォルトのENTRYPOINT
はsh -c
です(そして、sh
セッションでは tput がterminfo
を使用するため、tput line
はうまく機能しないと思います。その画像のbashのみに設定される可能性のあるデータベース)
ENTRYPOINT
をbash -c
で上書きして、それがうまく機能するかどうかを確認できます。
ただし、コマンドラインからは機能しません。
docker run --entrypoint /bin/bash --rm -it ubuntu:16.04 -i -c 'tput lines'
24
カスタム画像を定義するオプションをチェックします。
FROM ubuntu:16.04
ENTRYPOINT ["/bin/bash", "-c"]
ただし、結果は同じです。
docker run --rm -it u 'tput lines'
24
ただし、これは「機能」します。
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash" ]
と:
docker@default:/c/Users/vonc/prog/testsu$ docker run --rm -it u -i -c 'ls; tput lines'
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
48
同じコマンドが時々24を返すので、同期の問題があるかもしれません。
実際、次のalwaysは、「ではなく」を返します。
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ]
docker run --rm -it u -c 'sleep 0.1; ls; tput lines'
48
docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"
スリープの成功を考えると、ドッカーは実行中のコマンドでコンテナーを起動し、一度起動すると、クライアントは実行中のコンテナーにアタッチします。通常、数ミリ秒かかるもの。
それは私に別のアイデアを与えました:
docker@default:/c/Users/vonc/prog/testsu$
docker run --entrypoint='/bin/bash' --name ub -d -it ubuntu:16.04
0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b
docker@default:/c/Users/vonc/prog/testsu$
d attach ub
root@0d9b8783afbb:/# tput lines
48
root@0d9b8783afbb:/# exit
exit
docker@default:/c/Users/vonc/prog/testsu$ drmae
0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b
接続されたセッション内のtput lines
は正常に機能します。
(drmae
エイリアスで、「 古いおよび使用されていないDockerイメージを削除する方法 」を参照してください)
コンテナが作成され、デフォルト(
80x24
)で開始され、その後(-it
の場合)セッションがアタッチされます。
セッションは端末のサイズを指定しています。
「 コンテナのサイズ変更TTY API」を参照してください。
DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee43a/resize?h=46&w=221
詳細については、 docker issue 2545 を参照してください。
に関連しています 問題10341「コンテナの作成または開始は、高さ/幅のパラメータを受け入れる必要があります」 。 Aleksa Sarai(cyphar) を追加(2016年9月):
これは実際にruntime-spec内で再びポップアップしました( opencontainers/runtime-spec PR 56 )。
基本的に、Windowsは最初の起動時にコンソールサイズを設定する機能を必要とするため、すべてのプラットフォームに追加する可能性があります。
OP silgon は api/client/container/run.go
のコードを指します:
// Telling the Windows daemon the initial size of the tty during start makes
// a far better user experience rather than relying on subsequent resizes
// to cause things to catch up.
if runtime.GOOS == "windows" {
hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.GetTtySize()
}
論理的な質問:
linuxでもこのプロパティを使用し、その値を使用して初期コンソールサイズを設定するのは理にかなっていますか?
Kenfe-MickaëlLaventure(mlaventure
) があり、新しいパッチが Docker 1.1 になります。
次のコマンドでgoinside
コマンドラインツールをインストールできます。
Sudo npm install -g goinside
そして、適切な端末サイズのドッカーコンテナ内に移動します。
goinside docker_container_name
@ VonC answer のおかげで、~/.profile
に入れたシンプルなbashスニペットでこの問題の解決策が得られました
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside
これで、ターミナルサイズの問題なしに、ドッカーコンテナ内に移動できます。
$ goinside containername
goinside
関数を使用する前に、source ~/.profile
を覚えておいてください。
(以下のコメントのいずれかで共有されているため)goinside
のオートコンプリートを有効にする場合は、.profile
でこのスニペットを使用できます。
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export -f goinside;
zsh
をデフォルトの端末として使用している場合は、~/.zshrc
ファイル内でこのスニペットを使用できます。
autoload bashcompinit
bashcompinit
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export goinside;
行の問題に遭遇することなくコンテナ内でbashを実行する良い方法は here :
docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash
sh
対terminfoに関するコメントは、ほとんど無関係です。関連する部分(与えられた答えでは明確ではない)は、コマンドの実行方法です。 tput
は、次の順序で3つの機能をチェックします( setupterm
を使用):
TERM=xterm
、24by80)、LINES
およびCOLUMNS
環境変数。対話型シェルcouldなしで実行されるコマンドは、現在のウィンドウサイズを取得できない方法で実行されます。たとえば、それはssh
(-t
オプション)。また、DockerがLINES
およびCOLUMNS
変数を設定することは(無意味ですが)可能です。
動作を説明するには、ケース(1)または(3)のいずれかで十分です。時間遅延や人種を導入しても、それはできません。
Docker 18.06で修正されました: https://github.com/moby/moby/issues/33794#issuecomment-406814439
バージョンDocker version 18.06.1-ce, build e68fc7a
でテストしました。同じ問題があるようです。ただし、 github issue の人の1人が 実用的な回避策 を示しました。
docker run --rm -it -e COLUMNS=$COLUMNS -e LINES=$LINES -e TERM=$TERM -it ubuntu:16.04 tput lines