Docker exec / run shell command nesting

15

Una breve introducción al caso de uso:

Estoy usando un dockercontenedor para ejecutar mis gopruebas usando go test ./.... Esto se puede lograr fácilmente usando docker exec <container> /bin/sh -c "go test ./...". Lamentablemente, se go test ./...ejecuta en todos los subdirectorios y me gustaría excluir uno (el directorio de proveedores).

La solución recomendada para esto es usar el siguiente comando:, de go test $(go list ./... | grep -v '<excluded>'alguna manera, esto me deja con el siguiente resultado:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (He probado esto tanto en ejecución como en ejecución, pero probablemente usan el mismo núcleo).

Cuando me meto en el contenedor usando docker exec -it <container_id> /bin/shy ejecuto exactamente el mismo comando, funciona de maravilla.

Parece que ejecutar comandos de shell a través de docker exec / run no admite ningún comando anidado con $()?

Wesley van Opdorp
fuente
¿Qué comando exactamente ejecutaste? En $(go list ./... | grep -v '<excluded>', que <excluded>es?
Cuonglm
Es un directorio, vendorpor ejemplo.
Wesley van Opdorp
44
De acuerdo, tenga en cuenta que $(...)su shell lo expandió entre comillas dobles antes de que se ejecutara dentro del contenedor acoplable. Entonces, el problema puede provenir de su contenido de directorio actual. Hizo docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'el trabajo?
Cuonglm
¿Por qué no ejecutar los comandos desde un script ?
030

Respuestas:

30

Su comando puede no funcionar como esperaba gracias a un error común de bash:

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

El comando que está intentando ejecutar realizará la expansión de la subshell $()en su host porque está entre comillas dobles.

Esto se puede resolver con una simple cita de su comando como lo sugiere @cuonglm en los comentarios de la pregunta.

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

EDITAR: una pequeña demostración

[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
fuente
0

De go test --help:

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

Así que supongo que algo así go test -run "(!vendor)" ./...se saltaría esa carpeta en particular.

Marcel
fuente
Gracias Marcel, esto funciona! Desafortunadamente, enumera todos los directorios en los que no coincide con ninguna prueba, enumerando todo el directorio de proveedores con "sin archivos de prueba".
Wesley van Opdorp
Bueno, siempre puedes filtrarlos:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel