Docker exec/run shell 命令嵌套

Docker exec/run shell 命令嵌套

用例简单介绍:

我正在使用docker容器来运行我的go测试go test ./...。这可以通过使用轻松实现docker exec <container> /bin/sh -c "go test ./..."。不幸的是,go test ./...它会在所有子目录中运行,我想排除一个(供应商目录)。

建议的解决方案是使用以下命令:go test $(go list ./... | grep -v '<excluded>',不知何故,这给我留下了以下结果:

docker run golang:1.6.2-alpine /bin/sh -c "go test "(我已经在运行和执行上测试了这一点,但它们可能使用相同的核心)。

当我使用 ssh 进入容器docker exec -it <container_id> /bin/sh并运行完全相同的命令时,它就像魔法一样运行。

似乎通过 docker exec/run 执行 shell 命令不支持任何嵌套的命令$()

答案1

由于常见的 bash 陷阱,你的命令可能无法按预期工作:

docker exec <container> /bin/sh -c "go test $(go list ./... | grep -v '<excluded>')"

您尝试运行的命令将$()在您的主机上执行子 shell 的扩展,因为它位于双引号内。

可以按照问题评论中@cuonglm 的建议,通过单引号您的命令来解决此问题。

docker exec <container> /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'

编辑:一个小演示

[wbarnwell@host ~]$ docker run -it --rm busybox /bin/sh -c '$(whoami)'
/bin/sh: root: not found
[wbarnwell@host ~]$ docker run -it --rm busybox /bin/sh -c "$(whoami)"
/bin/sh: wbarnwell: not found

答案2

go test --help

-run regexp     Run only those tests and examples matching the regular
                expression.

所以我猜想类似的操作go test -run "(!vendor)" ./...会跳过那个特定的文件夹。

相关内容