【问题标题】:How to get ENV variable when doing Docker Inspect进行 Docker Inspect 时如何获取 ENV 变量
【发布时间】:2015-05-20 07:16:24
【问题描述】:

我想知道如何从 docker inspect 获取环境变量。

当我跑步时

docker inspect -f "{{.Config.Env.PATH}} " 1e2b8689cf06

我得到以下内容

FATA[0000] template: :1:9: executing "" at <.Config.Env.PATH>: can't evaluate field PATH in type interface {}

【问题讨论】:

    标签: docker


    【解决方案1】:

    可以直接用类似的命令获取

    docker inspect --format '{{ index (index .Config.Env) 1 }}' 797
    

    为我显示

    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    

    您会注意到将1 替换为0 就像

    docker inspect --format '{{ index (index .Config.Env) 0 }}' 797
    

    给了

    DISPLAY=:0
    

    事实上,我注意到以下各种docker inspect 从更一般到更精确的显示

    docker inspect --format '{{ (.NetworkSettings.Ports) }}' 87c
    map[8000/tcp:[map[HostIp:0.0.0.0 HostPort:49153]]]
    docker inspect --format '{{ ((index .NetworkSettings.Ports "8000/tcp") 0) }}' 87c
    [map[HostIp:0.0.0.0 HostPort:49153]]
    docker inspect --format '{{ index (index .NetworkSettings.Ports "8000/tcp") 0 }}' 87c
    map[HostIp:0.0.0.0 HostPort:49153]
    docker inspect --format '{{ (index (index .NetworkSettings.Ports "8000/tcp") 0).HostIp }}' 87c
    0.0.0.0
    docker inspect --format '{{ (index (index .NetworkSettings.Ports "8000/tcp") 0).HostPort }}' 87c
    49153
    

    注意:docker inspect -f 有效且更短,当然,我发布了“旧”语法。

    【讨论】:

    • 我创建了一个 PR 用于更新 docker inspect github.com/docker/docker/pull/13405 的文档
    • 如果要打印出所有环境变量,请使用以下命令:$docker inspect --format '{{ (index .Config.Env) }}'
    【解决方案2】:

    这似乎是不可能的,你可以列出环境变量,但不能只列出一个。

    来自docker commit doc

    $ sudo docker inspect -f "{{ .Config.Env }}" c3f279d17e0a
    [HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]
    
    $ sudo docker commit --change "ENV DEBUG true" c3f279d17e0a  SvenDowideit/testimage:version3
    f5283438590d
    
    $ sudo docker inspect -f "{{ .Config.Env }}" f5283438590d
    [HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin DEBUG=true]
    

    您可以打印它们:

    docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}'
    

    (如)

    $ docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' c3fa3ce1622b
    HOME=/
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    

    添加一个grep PATH,你只能得到PATH=xxx的值。


    user2915097 提到in the comments jq, a lightweight and flexible command-line JSON processor,在文章“Docker Inspect Template Magic ”中使用以很好地格式化所需字段:

    docker inspect -f '{{json .State}}' jenkins-data | jq '.StartedAt' 
      "2015-03-15T20:26:30.526796706Z"
    

    【讨论】:

    【解决方案3】:

    不需要任何外部工具的非常方便的选择是:

    docker exec 1e2b8689cf06 sh -c 'echo $PATH'
    

    诚然,这并没有使用docker inspect,但仍然......

    【讨论】:

    • 确实没有使用inspect 但是,仍然:这个答案非常简单、明确——我们看到的是我们正在寻找的变量(PATH)的名称,而不是一些神奇的索引——它是无需深入研究 GO 模式语言即可理解。
    • 如果你想获取所有环境变量,同样的方式只需将echo $PATH替换为printenv
    【解决方案4】:
    docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' CONTAINER-NAME | grep -P "^YOUR_VAR=" | sed 's/[^=]*=//'
    

    此解决方案需要 grep(带有 -P 选项)、sed 以及流水线处理它们的能力,但解决了大多数其他解决方案无法解决的 2 个问题。

    首先,它对变量名进行精确匹配。例如,如果您有以下变量:

    YOUR_VAR=value
    ANOTHER_YOUR_VAR=value2
    OTHER_VAR=YOUR_VAR
    

    您将正确收到value

    其次,它可以正确处理变量值包含= 字符的情况。例如:

    REBEL_OPTS=-Drebel.stats=false
    

    会正确地给你-Drebel.stats=false而不是false

    【讨论】:

      【解决方案5】:

      对于那些寻找仅使用 docker inspecttemplate-only 解决方案的人(当您不能只使用 shell 和 grep 等时) .),以下示例有效(从 docker 1.11+ 开始):

      > docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "SOME_VAR" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' *container_name*
      
      • 它甚至使用额外的 '=' 处理环境变量

      示例容器:

      > docker run -d -e --name sleeper SOME_VAR=key=value alpine:3.4 -sh 'sleep 9999'
      

      提取SOME_VAR

      > docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "SOME_VAR" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' sleeper
      

      【讨论】:

        【解决方案6】:

        我发现解析您感兴趣的环境变量 name 比依赖索引更好。

        echo $(docker inspect --format '{{ .Config.Env }}' mysql) |  tr ' ' '\n' | grep MYSQL_ROOT_PASSWORD | sed 's/^.*=//'
        

        【讨论】:

          【解决方案7】:

          Docker 格式化选项非常有限,jq 更强大:

          docker inspect 1e2b8689cf06 | jq '.[] | .Config.Env[] | select(test("^PATH=*"))'
          

          或将 Docker 格式与 jq 结合,同时仅将 Env 变量传递给 jq:

          docker inspect -f '{{json .Config.Env }}' 1e2b8689cf06 | jq '.[] | select(test("^PATH=*"))'
          

          假设容器中有printenv,你可以使用简单的grep

          docker exec -i 1e2b8689cf06 printenv | grep -oP '(?<=PATH=).*'
          

          -o 会从结果中省略匹配的PATH= 部分。语法比模板魔法更容易阅读。

          【讨论】:

            【解决方案8】:

            如果您希望能够检查操作是否成功,您可以使用:

            (
            for env in $(docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' ${2}); do
                if [[ "${env}" == "${1}"* ]]; then
                    echo ${env#${1}=}
                    exit 0
                fi
            done
            exit 1
            )
            

            这将打开一个子shell并根据是否找到返回:

            $ docker-extract PATH docker_image || echo not found
            /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            $ docker-extract NON_EXISTENT_ENV docker_image || echo not found
            not found
            $
            

            【讨论】:

            • 这是一个很好的方法,易于理解和重用。也许你应该添加上面的代码是shell脚本并且是docker-extract(.sh)的内容的信息。
            猜你喜欢
            • 2019-02-12
            • 2018-08-12
            • 1970-01-01
            • 2021-12-13
            • 2020-07-01
            • 1970-01-01
            • 2020-04-19
            • 2019-10-20
            • 1970-01-01
            相关资源
            最近更新 更多