Docker exec / run aninhamento de comandos shell

15

Uma breve introdução ao caso de uso:

Estou usando um dockercontêiner para executar meus gotestes usando go test ./.... Isso pode ser alcançado facilmente usando docker exec <container> /bin/sh -c "go test ./...". Infelizmente, go test ./...é executado em todos os subdiretórios e eu gostaria de excluir um (o diretório do fornecedor).

A solução recomendada para isso é usar o seguinte comando go test $(go list ./... | grep -v '<excluded>':, de alguma forma, isso me deixa com o seguinte resultado:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (Eu testei isso tanto no run quanto no exec, mas eles provavelmente usam o mesmo núcleo).

Quando ssh no contêiner usando docker exec -it <container_id> /bin/she executando exatamente o mesmo comando, ele funciona como um encanto.

Parece que a execução de comandos shell através do docker exec / run não suporta nenhum comando aninhado $()?

Wesley van Opdorp
fonte
Qual comando exatamente você executou? Em $(go list ./... | grep -v '<excluded>', o que <excluded>é?
cuonglm
É um diretório, vendorpor exemplo.
Wesley van Opdorp
4
OK, observe que ele $(...)foi expandido pelo seu shell entre aspas duplas antes de ser executado no contêiner do docker. Portanto, o problema pode vir do conteúdo atual do diretório. Funcionou docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'?
cuonglm
Por que não executar os comandos de um script ?
030

Respostas:

30

Seu comando pode não estar funcionando conforme o esperado, graças a uma captura comum do bash:

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

O comando que você está tentando executar executará a expansão do subshell $()no seu host, pois ele está entre aspas duplas.

Isso pode ser resolvido citando seu comando com uma única sugestão, conforme sugerido por @cuonglm nos comentários da pergunta.

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

EDIT: Uma pequena demonstração

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

De go test --help:

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

Então, acho que algo como go test -run "(!vendor)" ./...iria pular essa pasta específica.

Marcel
fonte
Obrigado Marcel, isso funciona! Infelizmente, ele lista todos os diretórios nos quais não corresponde a nenhum teste - listando todo o diretório do fornecedor com "sem arquivos de teste".
Wesley van Opdorp
Bem, você sempre pode filtrar aqueles:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel