Visibilidade de variáveis de ambiente passadas no container docker - mal-entendido

0

Vamos ver o exemplo a seguir:

[user@user~]$ sudo docker run -d -e XYZ=123 ubuntu sleep 10000
2543e7235fa9
[user@user~]$ sudo docker exec 2543e7235fa9 echo test
test
[user@user~]$ sudo docker exec 2543e7235fa9 echo $XYZ
<empty row>      
[user@user~]$ sudo docker exec -it 2543e7235fa9 bash
root@2543e7235fa9:/# echo $XYZ
123

Por que recebi <empty row> em vez de 123 ? E por que depois de executar e entrar no bash eu consigo ver XYZ=123 ?

    
por Spring fancy 25.02.2018 / 21:14

2 respostas

0

As duas coisas que você está perdendo aqui são:

  1. docker exec ... <command> não executa <command> em um shell por padrão, apenas executa <command> no contêiner sem um shell.

    Se você quiser executar um comando no docker em um shell não interativo, use:

    docker exec <container> bash -c '<command>'
    

    Se <command> tiver mais de uma palavra, ela precisará ser colocada entre aspas simples ou aspas duplas para que o comando inteiro seja passado para bash -c .

    por exemplo. sudo docker exec 2543e7235fa9 bash -c 'echo $XYZ'

  1. Quando você faz isso, há duas camadas importantes:

    • o shell em que você está executando sudo docker exec ... in (chame isso de "Shell A")
    • o shell que é executado dentro do contêiner (chame esse "Shell B").

    Se você não excluir a barra invertida ou citar o $ no shell A, o shell A interpolará seu próprio valor para $XYZ (mesmo que não tenha um , que retorna uma string vazia).

    Portanto, se XYZ=5 no Shell A, então seu sudo docker exec 2543e7235fa9 echo $XYZ é o mesmo que exec 2543e7235fa9 echo 5 (e não haveria shell B porque você não disse ao docker para executar bash -c ... ).

    Se você fizer escapar ou citar um $ , então ele será passado para o shell B como está, e o shell B irá interpolar seu valor para $XYZ .

Em outras palavras, use:

sudo docker exec 2543e7235fa9 bash -c 'echo $XYZ'

ou

sudo docker exec 2543e7235fa9 bash -c "echo \$XYZ"

O formulário com aspas simples é, na verdade, mais fácil de entender o que está fazendo e o que você deve usar na maior parte do tempo. Nenhuma interpolação variável acontece dentro de aspas simples, então o comando é passado exatamente como é para o shell B.

O formulário de aspas duplas é útil quando você precisa passar variáveis do shell A para o shell B. Se você também precisar passar um literal $ do que deve ser escapado com contrabarra. por exemplo. para obter o shell B para ecoar o $ABC do shell A e seu próprio $XYZ :

sudo docker exec 2543e7235fa9 bash -c "echo $ABC \$XYZ"

Se o $ABC do shell A for igual a 10 e o $XYZ do shell B for igual a 123, isso resultaria:

10 123

Nota: a menos que $XYZ seja definido em um dos arquivos de inicialização do shell B, ou com docker run -e XYZ=123 como você usou em seu exemplo (ou com -env-file ), ele não terá um valor.

    
por 26.02.2018 / 01:46
1

porque $XYZ é expandido pelo shell no qual você executa o comando docker exec . você precisa citá-lo para obter a string $XYZ .

sudo docker exec ... echo \$XYZ

existe realmente um mal-entendido - quais são os parâmetros e como eles se comportam no shell. quando você corre

any-command $XYZ

o any-command nunca vê $XYZ . seu shell o substitui com qualquer valor que o parâmetro tenha (nesse shell). Como você não tem nenhum parâmetro chamado XYZ ou está vazio, a linha de comando que você envia para o seu shell é

sudo docker exec 2543e7235fa9 echo
    
por 25.02.2018 / 21:32

Tags