2016-02-29 10 views
8

Chcę napisać wiersz tekstu do pliku tekstowego WEWNĄTRZ działającego kontenera dokowanego. Oto, co starałem dotąd:Docker exec - Napisz tekst do pliku w pojemniku

docker exec -d app_$i eval echo "server.url=$server_url" >> /home/app/.app/app.config 

Response:

/home/user/.app/app.config: No such file or directory 

Druga próba:

cfg_add="echo 'server.url=$server_url' >> /home/user/.app/app.config" 
docker exec -i app_$i eval $cfg_add 

Response:

exec: "eval": executable file not found in $PATH 

Jakieś pomysły?

+0

Dlaczego '-d' dla execer exec? – user2915097

+2

'eval' nie występuje w kontenerze. Jądro jest dzielone między hostem a kontenerem. Programy nie są. Jeśli zainstalowałeś 'nc' na twoim hoście, kontener nie będzie mógł go uruchomić, dopóki nie zainstalował go w swoim hoście. – Auzias

+0

@Auzias: Problem nie polega na tym, że 'eval' nie jest _present_ w kontenerze (prawdopodobnie jest to _shell wbudowany w powłokę kontenera), ale że _nie jest zewnętrznym narzędziem_, więc' docker exec' nie może wywołać to. – mklement0

Odpowiedz

22

eval jest powłoką wbudowane, natomiast docker exec wymaga zewnętrznego narzędzia będzie wywoływana, tak pomocą eval jest nie rozwiązaniem.

Zamiast wywołać wykonywalny powłoki w pojemniku (bash) wyraźnie i przekazać mu polecenie, aby wykonać jako ciąg, poprzez jego -c opcji:

docker exec "app_$i" bash -c "echo 'server.url=$server_url' >> /home/app/.app/app.config" 

za pomocą podwójnie -quoted string, aby przejść do bash -c, upewniając się, że bieżąca wykonuje najpierw interpolację ciągów, podczas gdy instancja kontenera bash widzi rozszerzony wynik jako literał, jako część wbudowanego , jedno-cytowanego ciągu.


chodzi o objawów:

  • /home/user/.app/app.config: No such file or directory odnotowano, ponieważ przekierowanie zamierzałeś zdarzyć w pojemniku faktycznie wydarzyło w skorupkach swojego gospodarza - i dlatego, reż. /home/user/.app najwyraźniej nie istnieje w systemie plików twojego hosta, polecenie nie powiodło się zasadniczo, przed powłoka hosta próbowała nawet wykonać polecenie (bash przerwie wykonywanie polecenia, jeśli przekierowanie wyjścia nie może zostać wykonane).

    • Tak więc, mimo że pierwsze polecenie zawarte również eval, jego zastosowanie nie powierzchniowych jako problem dopóki drugiego polecenia, które faktycznie zrobił zostanie wykonany.
  • exec: "eval": executable file not found in $PATH stało, ponieważ, jak stwierdzono, nie jest evalzewnętrzne narzędzie, ale powłoka wbudowane i docker exec może wykonać tylko zewnętrznych narzędzi.

+0

Świetna odpowiedź. Poniżej zamieściłem odpowiedź, nie zdając sobie sprawy, że chciał używać zmiennych zadeklarowanych przez gospodarza i takich. Twoja odpowiedź jest znacznie lepsza i wyjaśniła bardzo dobrze. Dzięki. – CtheGood

+0

@CtheGood: Dzięki; oprócz użycia zmiennych hosta, twoje polecenie nie zadziała, ponieważ musisz przekazać argumenty _separately_ do 'docker exec'; w twoim przypadku ciąg znaków "quotent_ single quoted" będzie interpretowany jako nazwa_command_, i spowoduje następujący błąd: 'exec:" echo \ "Hello World \"> test.txt ": plik wykonywalny nie został znaleziony w $ PATH' – mklement0

+0

Oto przykład tutaj, możesz pisać pliki z cytatami w nich. Na przykład chcesz napisać 'obj ['key'] = 'value'' do pliku o nazwie'/etc/config.py' 'doker exec" app_ $ i "bash -c' echo" obj [' "'key'" '] =' '' value '"'">/etc/config.py'' – Gourneau

4

Dodatkowo:

Jeśli trzeba napisać tekst z zewnątrz pojemnika, to działa również:

(docker exec -i container sh -c "cat > c.sql") < c.sql 

ta rura pozwoli Ci wejście do pojemnika. Oczywiście działałoby to również w przypadku zwykłego tekstu (bez pliku). Ważne jest, aby pominąć parametr -t.

Zobacz https://github.com/docker/docker/pull/9537

Update (w przypadku wystarczy skopiować pliki, a nie części plików):

Docker v17.03 posiada docker cp których kopie między lokalnymi i pojemnika fs: https://docs.docker.com/engine/reference/commandline/cp/#usage