Docker容器运行时LINES和COLUMNS值不正确的问题

108次阅读
没有评论

问题描述

在构建自己的Docker镜像时,用户使用了父镜像zshusers/zsh:5.8bitnami/minideb:bullseye。当他在不更改默认命令的情况下运行这些镜像中的任一镜像,并从交互式Shell中运行$ echo $COUMNSecho $LINES命令时,终端的正确尺寸会显示出来。但当他使用以下Docker文件创建子镜像时,大部分时间内打印的LINES/COLUMNS值是不正确的(设置为某个固定的值)。他不想让用户每次都传递-e LINES=$LINES参数。是否可以在以下Docker文件中进行更改,以便其中打包的应用程序始终获得周围终端的大小?

# syntax=docker/dockerfile:1
FROM bitnami/minideb:bullseye
WORKDIR /app
COPY . .
RUN apt update && apt install -y less zsh
ENV LC_ALL="C.UTF-8"
ENV TERM="xterm-256color"
ENTRYPOINT ["bash", "-lc"]
CMD ["zsh -lc 'echo $LINES,$COLUMNS; stty size'"]

下面是输出的示例。你可以看到,每次打印的大小都是不同的。如果这还不足够,甚至在同一次运行中echo $LINES,$COLUMNSstty size的输出也不同!

❯ docker build -t helloworld .
[+] Building 5.8s (13/13) FINISHED
...
❯ docker run --rm -it helloworld
41,113
41 113
❯ docker run --rm -it helloworld
24,800
24 800
...

此外,下面是$ neofetch命令的输出:

❯ neofetch
                    c.'
          reportaman@macos.local
                 ,xNMM.          ---------------------
               .OMMMMo           OS: macOS 13.0.1 22A400 arm64
               lMM"              Host: MacBookPro18,2
     .;loddo:.  .olloddol;.      Kernel: 22.1.0
       cKMMMMMMMMMMNWMMMMMMMMMM0:    Uptime: 4 hours, 19 mins
 .KMMMMMMMMMMMMMMMMMMMMMMMWd.    Packages: 358 (brew)
 XMMMMMMMMMMMMMMMMMMMMMMMX.      Shell: zsh 5.8.1
;MMMMMMMMMMMMMMMMMMMMMMMM:       Resolution: 2056x1329
:MMMMMMMMMMMMMMMMMMMMMMMM:       DE: Aqua
:MMMMMMMMMMMMMMMMMMMMMMMM:      WM: Quartz Compositor
.OMMMMMMMMMMMMMMMMMMMMMMMA.      WM Theme: Blue (Dark)
  "XMMMMMMMMMMMMMMMMMMMMMMP"   Terminal: tmux
    "XMMMMMMMMMMMMMMMMMMMM"     CPU: Apple M1 Max
      "OMMMMMMMMMMMMMMMMM"       GPU: Apple M1 Max
        ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
          ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
            ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
              ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                  ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                    ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                      ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                        ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                          ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                            ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                              ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB
                                ;KMMMMMMMWXXWMMMMMk.      Memory: 23708MiB / 32768MiB

解决方案

方案1:环境变量传递

如果要确保子镜像中的应用程序始终获取正确的终端大小,可以在Dockerfile中使用ENV指令将环境变量LINESCOLUMNS设置为终端的实际大小。这样在容器启动时,这些环境变量将被传递给应用程序。
以下是在Dockerfile中添加环境变量的示例:

# syntax=docker/dockerfile:1
FROM bitnami/minideb:bullseye
WORKDIR /app
COPY . .
RUN apt update && apt install -y less zsh
ENV LC_ALL="C.UTF-8"
ENV TERM="xterm-256color"
ENV LINES=$LINES
ENV COLUMNS=$COLUMNS
ENTRYPOINT ["bash", "-lc"]
CMD ["zsh -lc 'echo $LINES,$COLUMNS; stty size'"]

通过在ENV指令中设置LINESCOLUMNS环境变量,容器内的应用程序将始终获得与终端大小相匹配的值。这样,用户就不再需要每次手动传递环境变量。

方案2:Shell 脚本

另一种方法是使用一个启动脚本来替代直接在Dockerfile中设置环境变量。这样可以确保在容器启动时动态获取终端的大小,并将这些值传递给应用程序。下面是一个示例的启动脚本:
“`bash

!/bin/bash

获取终端的行数和列数

LINES=$(tput

正文完