Docker exec / run nesting nesting

15

Krótkie wprowadzenie do przypadku użycia:

Używam dockerkontenera do uruchamiania gotestów przy użyciu go test ./.... Można to łatwo osiągnąć za pomocą docker exec <container> /bin/sh -c "go test ./...". Niestety go test ./...działa we wszystkich podkatalogach i chciałbym wykluczyć jeden (katalog dostawcy).

Zalecanym rozwiązaniem jest użycie następującego polecenia: go test $(go list ./... | grep -v '<excluded>'w jakiś sposób pozostawia mi to następujący wynik:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (Testowałem to zarówno w trybie run, jak i exec, ale prawdopodobnie używają tego samego rdzenia).

Kiedy ssh do kontenera używam docker exec -it <container_id> /bin/shi uruchamiam dokładnie to samo polecenie, działa to jak urok.

Wydaje się, że wykonywanie poleceń powłoki przez exec / run dokera nie obsługuje żadnych zagnieżdżonych poleceń $()?

Wesley van Opdorp
źródło
Jakie dokładnie polecenie wykonałeś? W $(go list ./... | grep -v '<excluded>'czym <excluded>jest?
cuonglm
Na przykład jest to katalog vendor.
Wesley van Opdorp,
4
OK, więc zwróć uwagę, że $(...)został rozszerzony przez twoją powłokę wewnątrz podwójnych cudzysłowów, zanim została uruchomiona w kontenerze dokera. Problem może pochodzić z bieżącej zawartości katalogu. Czy docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'działa?
cuonglm,
Dlaczego nie uruchomić poleceń ze skryptu ?
030

Odpowiedzi:

30

Twoje polecenie może nie działać zgodnie z oczekiwaniami, dzięki wspólnej gotcha bash:

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

Polecenie, które próbujesz uruchomić, spowoduje rozwinięcie podpowłoki $()na hoście, ponieważ znajduje się ona w podwójnych cudzysłowach.

Można to rozwiązać poprzez pojedyncze zacytowanie polecenia zgodnie z sugestią @cuonglm w komentarzach do pytania.

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

EDYCJA: Mała wersja demonstracyjna

[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
źródło
0

Od go test --help:

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

Sądzę więc, że coś takiego go test -run "(!vendor)" ./...pomija ten konkretny folder.

Marcel
źródło
Dzięki Marcel, to działa! Niestety wyświetla listę wszystkich katalogów, w których nie pasuje do żadnych testów - wyświetlając cały katalog dostawcy z „bez plików testowych”.
Wesley van Opdorp
Cóż, zawsze możesz filtrować te:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel