【问题标题】:Docker exec quoting variablesDocker exec 引用变量
【发布时间】:2019-01-30 22:11:42
【问题描述】:

我想知道是否有办法做到这一点

假设dockerfile 包含这一行,指定可执行文件的路径

ENV CLI /usr/local/bin/myprogram

我希望能够通过exec 命令使用 ENV 变量名调用此程序。

例如 docker exec -it <my container> 'echo something-${CLI} 期待 something-/usr/local/bin/myprogram

但是返回:

OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"${CLI} do something\": executable file not found in $PATH": unknown

【问题讨论】:

    标签: bash docker escaping dockerfile


    【解决方案1】:

    好的,我找到了一种方法,你需要做的就是使用 bash 评估命令

    docker exec -it <container id> bash -c 'echo something-${CLI}'

    返回something-/usr/local/bin/myprogram

    如果容器中还没有设置CLI环境变量,也可以传入如:

    docker exec -it -e CLI=/usr/local/bin/myprogram <container id> bash -c 'echo something-${CLI}'

    查看帮助文件:

     docker exec --help
    
     Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    
     Run a command in a running container
    
    Options:
    -d, --detach               Detached mode: run command in the background
    -e, --env list             Set environment variables
    ....
    

    【讨论】:

    • 我坚持我的声明,我质疑你理解甚至你自己的答案的能力。您的原始请求(在您编辑之前)是docker exec -it <my container> '${CLI} do something',这将不起作用,用法:docker exec [OPTIONS] CONTAINER COMMAND [ARG...],“COMMAND 应该是可执行文件,链接或引用的命令将不起作用”(参考。docs.docker.com/engine/reference/commandline/exec) .
    • @masseyb 那么你还没有理解这个问题
    • 不断告诉自己。 1 只改变预期结果的编辑,我的意思是肯定的,每个人都应该能够猜到你真正期待的 amirite。另外,喜欢双重标准,«正确的答案是 x 因为 ... »。为你的答案提供解释怎么样?
    【解决方案2】:

    在它的original revisiondocker exec -it <my container> '${CLI} do something' 中,期望${CLI} 将被/usr/local/bin/myprogram(作为exec COMMAND)替换,并且在作为ARG 传递给/usr/local/bin/myprogram 之后的所有内容都将不起作用,这有明确的记录:https://docs.docker.com/engine/reference/commandline/exec/

    COMMAND 应该是可执行文件,链接或引用的命令将不起作用。示例:

    docker exec -ti my_container "echo a && echo b" 不起作用,但是

    docker exec -ti my_container sh -c "echo a && echo b" 会。

    按照文档,这将按预期工作:docker exec -ti my_container sh -c "${CLI} foo"${CLI} 将在变量扩展后执行,并将参数传递给${CLI} 中设置的 shell 脚本(例如sh -c /usr/local/bin/myprogram foo)。

    或者,您可以将ENTRYPOINT 设置为您的脚本并使用CMD 或在命令行中使用docker run 传递参数,例如:

    鉴于以下目录结构:

    .
    ├── Dockerfile
    └── example.sh
    

    Dockerfile 内容:

    FROM ubuntu:18.04
    COPY example.sh /bin
    RUN chmod u+x /bin/example.sh
    ENTRYPOINT ["/bin/example.sh"]
    CMD ["bla"]
    

    还有example.sh的脚本内容:

    #!/bin/bash
    echo $1
    

    DockerfileENTRYPOINT 之后指定的CMD 将是您脚本的默认参数,您可以在命令行上覆盖默认参数(假设图像已构建并标记为example:0.1 ):

    user@host> docker run --rm example:0.1
    bla
    user@host> docker run --rm example:0.1 "arbitrary text"
    arbitrary text
    

    注意:这是我在DockerfileENTRYPOINTCMD 之间的区别的文章:https://medium.freecodecamp.org/docker-entrypoint-cmd-dockerfile-best-practices-abc591c30e21

    【讨论】:

    • 我不确定您是否理解我的问题,因为您提出的解决方案没有相关性
    • @Ben 我对您的 ~“如果可能”的问题的回答是否定的,我不这么认为,因为在 docker exec 命令之后指定的环境变量似乎是在评估主机,例如export CLI=random 在您的主机上,然后docker exec -it <your_container> ${CLI} do something 不带引号将用主机上设置的值替换${CLI}(如果在您的环境中设置 - 错误:... process caused "exec: \"random\": executable file not found in $PATH": unknown),不在容器中并且带引号的变量不会被替换因此你的错误。
    • 是的,一个简单的“否”就足够了,但是您与 ENTRYPOINT 的提案确实没有相关性。我没有问如何设置可执行文件,我想做的只是在 exec 上下文中引用容器局部变量。以docker exec -it <my container> 'echo ${CLI}' 为例
    • @Ben 我在第一行回答了你的问题,如果你愿意,可以忽略之后的所有内容,相同的差异。
    • I don't believe it's going to be possible 不能被视为答案。这意味着你不确定。正确答案是No, because ... <explanation>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2020-10-26
    • 2021-08-09
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多