Docker exec / run shellコマンドのネスト


15

ユースケースの簡単な紹介:

を使用しdockergoテストを実行するためにコンテナを使用していgo test ./...ます。これはを使用して簡単に実現できますdocker exec <container> /bin/sh -c "go test ./..."。残念ながらgo test ./...、すべてのサブディレクトリで実行されるため、1つ(ベンダーディレクトリ)を除外したいと思います。

このための推奨される解決策は、次のコマンドを使用するgo test $(go list ./... | grep -v '<excluded>'ことです。

docker run golang:1.6.2-alpine /bin/sh -c "go test " (私はこれをrunとexecの両方でテストしましたが、おそらく同じコアを使用しています)。

docker exec -it <container_id> /bin/shまったく同じコマンドを使用してコンテナにsshして実行すると、それは魅力のように機能します。

docker exec / runでシェルコマンドを実行すると、$()?でネストされたコマンドはサポートされないようです。


正確にどのコマンドを実行しましたか?では$(go list ./... | grep -v '<excluded>'、何<excluded>ですか?
クオンルム

vendorたとえば、ディレクトリです。
ウェスリーヴァンオプドルプ

4
OK、だから$(...)ドッカーコンテナー内で実行される前に、二重引用符でシェルによって展開されたことに注意してください。そのため、問題は現在のディレクトリのコンテンツに起因する可能性があります。docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'うまくいきましたか?
クオンルム

スクリプトからコマンド実行してみませんか?
030

回答:


30

一般的なbash gotchaのおかげで、コマンドが期待どおりに機能しない場合があります。

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

実行しようとしているコマンドは、$()二重引用符で囲まれているため、ホスト上のサブシェルの展開を実行します。

これは、質問コメントで@cuonglmが示唆するように、コマンドを単一引用符で囲むことで解決できます。

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

編集:小さなデモ

[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

0

からgo test --help

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

だから私はそのようなgo test -run "(!vendor)" ./...特定のフォルダーをスキップすると思います。


ありがとう、マルセル、これはうまくいく!残念ながら、どのテストとも一致しないすべてのディレクトリがリストされます。ベンダーディレクトリ全体が「テストファイルなし」でリストされます。
ウェスリーヴァンOpdorp

さて、あなたは常にそれらをフィルタリングすることができます:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
マルセル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.