Docker exec / run shell command nesting

15

Pengantar singkat tentang use case:

Saya menggunakan dockerwadah untuk menjalankan gotes saya menggunakan go test ./.... Ini dapat dicapai dengan mudah menggunakan docker exec <container> /bin/sh -c "go test ./...". Sayangnya go test ./...berjalan di semua subdirektori dan saya ingin mengecualikan satu (direktori vendor).

Solusi yang disarankan untuk ini adalah menggunakan perintah berikut:, go test $(go list ./... | grep -v '<excluded>'entah bagaimana ini membuat saya dengan hasil berikut:

docker run golang:1.6.2-alpine /bin/sh -c "go test " (Saya telah menguji ini pada kedua menjalankan dan exec, tetapi mereka mungkin menggunakan inti yang sama).

Ketika saya ssh ke dalam wadah menggunakan docker exec -it <container_id> /bin/shdan menjalankan perintah yang sama persis, itu berfungsi seperti pesona.

Tampaknya mengeksekusi perintah shell melalui docker exec / run tidak mendukung perintah yang bersarang $()?

Wesley van Opdorp
sumber
Apa tepatnya perintah yang Anda jalankan? Dalam $(go list ./... | grep -v '<excluded>', apa <excluded>itu?
cuonglm
Itu direktori, vendormisalnya.
Wesley van Opdorp
4
OK, jadi perhatikan bahwa $(...)diperluas oleh shell Anda di dalam tanda kutip ganda sebelum dijalankan di dalam wadah buruh pelabuhan. Jadi, masalahnya mungkin berasal dari konten direktori Anda saat ini. Berhasil docker exec container /bin/sh -c 'go test $(go list ./... | grep -v "<excluded>")'?
cuonglm
Mengapa tidak menjalankan perintah dari skrip ?
030

Jawaban:

30

Perintah Anda mungkin tidak berfungsi seperti yang Anda harapkan berkat bash gotcha yang umum:

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

Perintah yang Anda coba jalankan akan melakukan perluasan subshell $()pada host Anda karena ada di dalam tanda kutip ganda.

Ini dapat diselesaikan dengan mengutip perintah Anda tunggal seperti yang disarankan oleh @cuonglm di komentar pertanyaan.

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

EDIT: Demo kecil

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

Dari go test --help:

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

Jadi saya kira sesuatu seperti go test -run "(!vendor)" ./...akan melewati folder itu.

Marcel
sumber
Terima kasih Marcel, ini berhasil! Sayangnya itu memang mencantumkan semua direktori yang tidak cocok dengan tes apa pun - mendaftar seluruh direktori vendor dengan "tidak ada file pengujian".
Wesley van Opdorp
Nah, Anda selalu dapat menyaring mereka:$(go test -run "(!vendor)" ./... | egrep -v "no test files\|vendor")
Marcel