Por que as variáveis de ambiente são diferentes com 'bash -c'?

5

Como é o seguinte, ou seja, ecoando $PATH diretamente de bash -c :

docker exec -i -t my_container bash -c "echo $PATH"

retorna um valor diferente para $PATH do que segue, ou seja, iniciar uma sessão bash interativa e ecoar a $PATH ?

docker exec -i -t my_container bash 
root@21e6d898c3c2:/# echo $PATH

Para dar algum contexto a essa questão, eu gostaria de executar um comando no container com docker exec , e este comando está no caminho se eu iniciar uma sessão bash interativa, mas não se eu apenas executar o comando.

Usar o caminho completo do executável não é uma solução alternativa nesse caso, pois o comando depende de outras variáveis de ambiente que, assim como PATH , são definidas em uma sessão interativa do bash, mas não se eu executar o comando em linha reta.

    
por Alessandro Vernet 23.11.2016 / 20:14

3 respostas

2

Quando -c é especificado, bash não está sendo executado como interativo ou um login shell para que ele não leia os mesmos scripts de inicialização. Qualquer coisa definida em /etc/profile , ~/.bash_profile , ~/.bash_login ou ~/.profile seria definitivamente ignorada.

Além disso, conforme explicado na página bash man:

Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by the remote shell daemon, usually rshd, or the secure shell daemon sshd. If bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc and ~/.bashrc, if these files exist and are readable.

Então, se você não acha que está se conectando através da rede, talvez não leia o arquivo .bashrc , o que pula tudo que não foi ignorado na etapa anterior.

solução

Para contornar esse problema, eu criaria um script que definisse o PATH como algo adequado e depois executasse o comando. Se você quiser usar os arquivos .profile ou outros arquivos existentes, poderá fazer a sua fonte seu roteiro.

    
por 23.11.2016 / 22:43
2

No seu primeiro exemplo:

docker exec -i -t my_container bash -c "echo $PATH"

Isso avaliará a variável $PATH com seu shell no cliente do docker, fora do contêiner e, em seguida, transmitirá o valor expandido como o comando a ser executado dentro do contêiner. Você pode comparar o valor acima para executar echo $PATH na linha de comando fora da janela de encaixe e ver se eles são iguais.

No seu segundo exemplo:

docker exec -i -t my_container bash 
root@21e6d898c3c2:/# echo $PATH

Isso avaliará a variável $PATH dentro do contêiner.

Você pode escapar do seu primeiro exemplo ou fazer uma citação simples para evitar que o bash shell em sua estação de trabalho o expanda, para que ele seja avaliado dentro do contêiner. Qualquer um dos seguintes procedimentos funcionaria:

docker exec -i -t my_container bash -c "echo \$PATH"
docker exec -i -t my_container bash -c 'echo $PATH'
    
por 27.11.2017 / 22:22
0

tente a opção -l para o bash. Ele será executado no shell de login e carregará o / etc / profile.

docker exec -i -t my_container bash -lc "echo $PATH"
    
por 22.11.2017 / 22:23

Tags