Imbrication de la commande shell exec / run de Docker

15

Une brève introduction au cas d'utilisation:

J'utilise un dockerconteneur pour exécuter mes gotests en utilisant go test ./.... Ceci peut être réalisé facilement en utilisant docker exec <container> /bin/sh -c "go test ./...". Malheureusement, go test ./...s'exécute dans tous les sous-répertoires et j'aimerais en exclure un (le répertoire des fournisseurs).

La solution recommandée pour cela utilise la commande suivante go test $(go list ./... | grep -v '<excluded>':, cela me laisse en quelque sorte le résultat suivant:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (J'ai testé cela sur run et exec, mais ils utilisent probablement le même noyau).

Lorsque je ssh dans le conteneur en utilisant docker exec -it <container_id> /bin/shet en exécutant exactement la même commande, cela fonctionne comme un charme.

Il semble que l'exécution de commandes shell via le docker exec / run ne prend en charge aucune commande imbriquée $()?

Wesley van Opdorp
la source
Quelle commande avez-vous exécutée exactement? Dans $(go list ./... | grep -v '<excluded>', qu'est-ce que <excluded>c'est?
cuonglm
C'est un répertoire, vendorpar exemple.
Wesley van Opdorp
4
OK, notez donc que $(...)votre shell a été développé par des guillemets doubles avant d'être exécuté à l'intérieur du conteneur Docker. Le problème peut donc provenir du contenu de votre répertoire actuel. A docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'fonctionné?
cuonglm
Pourquoi ne pas exécuter les commandes à partir d'un script ?
030

Réponses:

30

Votre commande peut ne pas fonctionner comme prévu grâce à un gotcha bash commun:

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

La commande que vous essayez d'exécuter effectuera l'expansion du sous-shell $()sur votre hôte car il est entre guillemets doubles.

Cela peut être résolu en citant simplement votre commande comme suggéré par @cuonglm dans les commentaires de la question.

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

EDIT: Une petite démo

[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
la source
0

De go test --help:

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

Donc, je suppose que quelque chose comme go test -run "(!vendor)" ./...sauter ce dossier particulier.

Marcel
la source
Merci Marcel, ça marche! Malheureusement, il répertorie tous les répertoires dans lesquels il ne correspond à aucun test - répertoriant l'intégralité du répertoire du fournisseur avec "aucun fichier de test".
Wesley van Opdorp
Eh bien, vous pouvez toujours les filtrer:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel