【问题标题】:Adding interactive user input e.g., `read` in a Docker container在 Docker 容器中添加交互式用户输入,例如 `read`
【发布时间】:2020-09-05 03:28:34
【问题描述】:

我想制作一个可以执行以下操作的 Docker 映像:

  1. 使用read获取用户输入并将其存储在局部变量中
  2. 将该变量用于以后的命令

使用我有以下 Dockerfile:

FROM ubuntu
RUN ["echo", "'Input something: '"]
RUN ["read", "some_var"]
RUN ["echo", "You wrote $some_var!"]

在运行 docker build 时,会产生以下输出:

Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM ubuntu
 ---> 4e2eef94cd6b
Step 2/4 : RUN ["echo", "'Input something: '"]
 ---> Using cache
 ---> a9d967721ade
Step 3/4 : RUN ["read", "some_var"]
 ---> Running in e1c603e2d376
OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"read\": executable file not found in $PATH": unknown

read 似乎是一个内置的 bash “函数”,因为 which read 没有产生任何结果。 我用["/bin/bash -c read", "some_var"]["/bin/bash", "-c", "read", "some_var"] 替换了["read", "some_var"],但都产生了以下结果:

...
Step 3/4 : RUN ["/bin/bash -c read", "some_var"]
 ---> Running in 6036267781a4
OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash -c read\": stat /bin/bash -c read: no such file or directory": unknown
...
Step 3/4 : RUN ["/bin/bash", "-c", "read", "some_var"]
 ---> Running in 947dda3a9a6c
The command '/bin/bash -c read some_var' returned a non-zero code: 1

此外,我还用RUN read some_var 替换了它,但结果如下:

...
Step 3/4 : RUN read some_var
 ---> Running in de0444c67386
The command '/bin/sh -c read some_var' returned a non-zero code: 1

谁能帮我解决这个问题?

【问题讨论】:

    标签: linux bash docker stdin


    【解决方案1】:

    一种解决方案是使用外部 shell 脚本并使用ENTRYPOINT

    run.sh的内容:

    #!/bin/bash
    echo "Input something!"
    read some_var
    echo "You wrote ${some_var}!"
    

    Dockerfile的内容:

    FROM ubuntu
    COPY "run.sh" .
    RUN ["chmod", "+x", "./run.sh"]
    ENTRYPOINT [ "./run.sh" ]
    

    这将允许./run.sh 在容器旋转时运行:

    $ docker build -t test .
    Step 1/4 : FROM ubuntu
     ---> 4e2eef94cd6b
    Step 2/4 : COPY "run.sh" .
     ---> 37225979730d
    Step 3/4 : RUN ["chmod", "+x", "./run.sh"]
     ---> Running in 5f20ded00739
    Removing intermediate container 5f20ded00739
     ---> 41174edb932c
    Step 4/4 : ENTRYPOINT [ "./run.sh" ]
     ---> Running in bed7717c1242
    Removing intermediate container bed7717c1242
     ---> 554da7be7972
    Successfully built 554da7be7972
    Successfully tagged test:latest
    
    $ docker run -it test
    Input something!
    Test message 
    You wrote Test message!
    

    【讨论】:

    • (请记住,运行docker 命令通常需要sudo 权限——您几乎可以轻松地使用它来根主机——并且容器将无法访问用户的主目录或其他内容。在没有 Docker 的情况下运行 ./run.sh 会更容易。)
    • 什么意思?虽然在这种情况下run.sh 是一个简单的 stdin+stdout 操作,但对于需要容器化的更复杂的操作可能并非如此。另外我在我的环境中使用了无根 docker,但是 root 用户不能访问系统的所有文件吗?
    • 没有特殊配置:尝试docker run --rm -it -u root alpine sh 在调试容器中获取交互式根shell,看看你能看到什么,不能看到什么。
    • @DavidMaze 是的,这会以 root 身份从 Alpine 映像创建一个新的。我不希望主机中的主文件夹中的任何文件都可以使用,除非我要进行一些绑定。在我的 Dockerfile 中,虽然我使用了 COPY 操作,但我希望在同一文件夹中的一个名为 run.sh 的本地文件可在图像中使用。自从我在深夜写这篇文章以来,有点澄清:当我说“root 用户不能访问系统的所有文件”时,我指的是运行 Docker 的 root 用户(sudo docker [cmd...])。我认为这根本不相关,很抱歉造成混淆。
    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 2020-05-05
    相关资源
    最近更新 更多