Verschachtelung des Docker-Befehls exec / run shell

15

Eine kurze Einführung in den Anwendungsfall:

Ich verwende einen dockerContainer, um meine goTests mit auszuführen go test ./.... Dies kann leicht mit erreicht werden docker exec <container> /bin/sh -c "go test ./...". Läuft leider go test ./...über alle Unterverzeichnisse und ich möchte eines ausschließen (das Anbieterverzeichnis).

Die empfohlene Lösung hierfür ist der folgende Befehl go test $(go list ./... | grep -v '<excluded>':

docker run golang:1.6.2-alpine /bin/sh -c "go test " (Ich habe dies auf run und exec getestet, aber sie verwenden wahrscheinlich den gleichen Kern).

Wenn ich docker exec -it <container_id> /bin/shden gleichen Befehl verwende und in den Container stelle , funktioniert das wie ein Zauber.

Es scheint, dass die Ausführung von Shell-Befehlen durch das Docker exec / run keine Befehle unterstützt, die mit verschachtelt sind $().

Wesley van Opdorp
quelle
Welchen Befehl hast du genau ausgeführt? In $(go list ./... | grep -v '<excluded>', was <excluded>ist?
Dienstag,
Es ist vendorzum Beispiel ein Verzeichnis .
Wesley van Opdorp
4
OK, beachten Sie also, dass $(...)Ihre Shell in doppelte Anführungszeichen gesetzt wurde, bevor sie im Docker-Container ausgeführt wurde. Das Problem kann also von Ihrem aktuellen Verzeichnisinhalt herrühren. Hat docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'funktioniert
Dienstag,
Warum nicht die Befehle von einem Skript aus ausführen ?
30.

Antworten:

30

Ihr Befehl funktioniert möglicherweise nicht wie erwartet, dank einer allgemeinen Bash-Aktion:

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

Der Befehl, den Sie ausführen möchten, führt die Erweiterung der Subshell $()auf Ihrem Host durch, da diese in doppelten Anführungszeichen steht.

Dies kann gelöst werden, indem Sie Ihren Befehl in Anführungszeichen setzen, wie von @cuonglm in den Fragenkommentaren vorgeschlagen.

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

EDIT: Eine kleine 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
quelle
0

Von go test --help:

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

Ich denke, so etwas go test -run "(!vendor)" ./...würde diesen bestimmten Ordner überspringen.

Marcel
quelle
Danke Marcel, das funktioniert! Leider listet es alle Verzeichnisse auf, in denen es keinen Tests entspricht - das gesamte Anbieterverzeichnis mit "keine Testdateien".
Wesley van Opdorp
Nun, Sie können diese immer filtern:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel