Como enviar variável para um shell script embutido?

26

Eu executo o seguinte script:

VAR="Test"
sh -c 'echo "Hello $VAR"'

Mas eu entendo:

# ./test.sh
Hello

Como posso enviar a variável VARdo meu script para o shell criado com sh -c '...'?

Matthieu Napoli
fonte

Respostas:

44

Use exportpara transformá-lo em uma variável de ambiente ou passe-o diretamente para o comando.

VAR="Test" sh -c 'echo "Hello $VAR"'

VAR="Test"
export VAR
sh -c 'echo "Hello $VAR"'

Evite usar aspas duplas no código do shell para permitir a interpolação, pois isso introduz vulnerabilidades de injeção de comando, como em:

sh -c "echo 'Olá $ VAR'"

causando uma reinicialização se chamado quando $VARcontém algo como';reboot #

Ignacio Vazquez-Abrams
fonte
Não é realmente prático (tenho várias variáveis ​​e não quero que sejam variáveis ​​de ambiente), mas funciona, obrigado!
Matthieu Napoli
3
@ Matthieu: Eles são definidos apenas como variáveis ​​de ambiente para os filhos do seu processo , se é isso que o preocupa.
Piskvor
5
Apenas para sua informação, você também pode fazer export var="Test"em uma linha.
user606723
@Piskvor bem, obrigado pela precisão, então é perfeito.
Matthieu Napoli
9

Aqui está outra maneira de passar variáveis sh -c(como argumentos posicionais):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}
ben
fonte
11
(+1) Para mantê-lo mais alinhado com a expectativa normal de $ 1 $ 2 para variáveis ​​de script, ele pode ter um valor fictício para $ 0. Isso permitirá $@que funcione conforme o esperado, por exemplo. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Peter.O
2
@ Peter.O Em vez de usar "_", eu usaria "sh" ou um nome sensível para atribuir a esse comando, já que isso $0é exibido nas mensagens de erro / aviso do shell.
Stéphane Chazelas
5

Se você não deseja exportá-los como variáveis ​​de ambiente, aqui está um truque que você pode fazer. Salve sua definição de variável em um arquivo .var_init.she origine -a em seu sub-shell da seguinte maneira:

.var_init.sh

VAR="Test"

na linha de comando:

sh -c ". .var_init.sh && echo \$VAR" # Make sure to properly escape the '$'

Dessa forma, você define suas variáveis ​​apenas na execução do seu subshell.

rahmu
fonte
... ouENV=.var_ini.sh sh -c '...'
Kusalananda
Observe que, se isso .var_init.shdeve ser procurado no diretório atual (ao contrário de $PATH), ele deve ser escrito. ./var_init.sh
Stéphane Chazelas