Por que a origem não funciona quando eu chamo bash -c

2

Eu quero executar um comando que origina um script para executar algum env. variáveis antes de executá-las, sem obtê-las no shell atual.

test.env

export test=1

Nenhum desses comandos ecoa o env. variável:

a) Isso não deveria funcionar? Não estou apenas executando esses comandos em um novo shell e retornando a saída?

$ bash -c "source test.env && echo $test"

b) Aqui eu executo o test.env e tento executar o echo $ test no mesmo processo usando exec.

$ bash -c "./test.env && exec echo $test"

c) Por fim, tentei fazer isso, já que era uma permutação possível. Mas ele executa test.env e o comando echo como processos separados.

$ bash -c "./test.env && echo $test"

E como posso fazer isso funcionar onde o env. variáveis são obtidas antes do segundo comando ser executado?

    
por Salami 08.06.2014 / 07:55

3 respostas

6

Você deve sair do sinal de dólar $ no seu primeiro comando, caso contrário bash irá expandi-lo antes que seu comando seja executado:

$ bash -c "source test.env && echo \$test"

Ou você deve usar aspas simples em vez de aspas duplas:

$ bash -c 'source test.env && echo $test'
    
por 08.06.2014 / 08:12
1

Se o objetivo for apenas manipular a configuração ENV antes de executar um processo e evitar afetar o shell atual, então exec ing o executável bash pode não ser a maneira mais eficiente de fazer isso.

( . /dev/fd/4 && echo "$i" ) 4<<\SCRIPT
    i='i is set here in the subshell'
#END
SCRIPT

echo ${i?but i isnt set here because it was set in the subshell}

OUTPUT

i is set here in the subshell
sh: line 5: i: but i isnt set here because it was set in the subshell

É claro que você pode substituir o link do descritor de arquivo do heredoc por um arquivo normal - eu o usei apenas para demonstrá-lo.

Mas se você fizer exec um processo externo - como bash ou qualquer outro - em vez de um shell embutido, você não precisará da subshell.

one=1 two=2 \
    bash -c 'echo "${cmd=This is command #}$one" 
             echo "${cmd}$two"'
echo "${one?this var was only set for the execed ENV}"

OUTPUT

This is command #1
This is command #2
sh: line 2: one: this var was only set for the execed ENV

E se esse processo externo for bash ou qualquer outro shell em conformidade com o padrão POSIX de aceitar -s tdin como padrão, você pode simplesmente escrever seu script diretamente em um arquivo |pipe ...

{ echo PS1=
  echo 'echo "$PS1"'
  cat /etc/skel/.bashrc
  echo 'echo "$PS1"'
} | bash
echo "${PS1:?unset here again}"

OUTPUT

#blank line from first echo
[\u@\h \W]\$
sh: line 7: PS1: unset here again
    
por 08.06.2014 / 09:22
0

Como escrito, o shell está expandindo $test antes de ser passado para o seu comando. Você pode impedir que isso aconteça usando ' em vez de " .

bash -c 'source test.env && echo $test'
    
por 08.06.2014 / 08:15