21

A short introduction to the use case:

I am using a docker container to run my go tests using go test ./.... This can be achieved easily using docker exec <container> /bin/sh -c "go test ./...". Unfortunately go test ./... runs across all subdirectories and I'd like to exclude one (the vendor directory).

The advised solution for this is using the following command: go test $(go list ./... | grep -v '<excluded>', somehow this leaves me with the following result:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (I have tested this on both run and exec, but they probably use the same core).

When I ssh into the container using docker exec -it <container_id> /bin/sh and run the exact same command, it works like a charm.

It seems that executing shell commands trough the docker exec/run does not support any commands nested with $()?

Will Barnwell
  • 760
  • 6
  • 9
Wesley van Opdorp
  • 291
  • 1
  • 3
  • 10
  • What exactly command did you run? In `$(go list ./... | grep -v ''`, what's `` is? – cuonglm Jun 13 '16 at 07:49
  • It's a directory, `vendor` for example. – Wesley van Opdorp Jun 13 '16 at 08:48
  • 4
    OK, so note that `$(...)` was expanded by your shell inside double quotes before it was run inside docker container. So, the issue may come from your current directory content. Did `docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "")'` work? – cuonglm Jun 13 '16 at 08:59
  • Why not run the commands [from a script](http://stackoverflow.com/a/31578527/2777965)? – 030 Jun 14 '16 at 17:15

2 Answers2

40

Your command may not be working as you expected thanks to a common bash gotcha:

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

The command you are trying to run will perform the expansion of the subshell $() on your host because it is inside double quotes.

This can be solved by single quoting your command as suggested by @cuonglm in the question comments.

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

EDIT: A little demo

[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
Will Barnwell
  • 760
  • 6
  • 9
0

From go test --help:

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

So I guess something like go test -run "(!vendor)" ./... would skip that particular folder.

Marcel
  • 1,730
  • 10
  • 15
  • Thanks Marcel, this works! Unfortunately it does list all directories in which it does not match any tests - listing the entire vendor directory with "no test files". – Wesley van Opdorp Jun 15 '16 at 11:23
  • Well, you can always filter those: `$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")` – Marcel Jun 15 '16 at 16:21