Normalmente, é possível definir uma variável de ambiente para um comando prefixando-o assim:
hello=hi bash -c 'echo $hello'
Eu também sei que podemos usar uma variável para substituir qualquer parte de uma invocação de comando como o seguinte:
$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"
Fiquei muito surpreso ao descobrir que você não pode usar uma variável para prefixar um comando para definir uma variável de ambiente. Caso de teste:
$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found
Por que não posso definir a variável de ambiente usando uma variável? A parte do prefixo é uma parte especial? Consegui fazer funcionar usando eval na frente, mas ainda não entendi o porquê. Estou usando o bash 4.4.
Eu suspeito que esta é a parte da sequência que está pegando você:
Isso é do manual de referência do Bash na seção sobre Expansão de comando simples.
No
cmd=bash
exemplo, nenhuma variável de ambiente é definida e o bash processa a linha de comando por meio da expansão de parâmetros, deixandobash -c "echo hi"
.No
prefix=hello=hi
exemplo, novamente não há atribuições de variáveis na primeira passagem, então o processamento continua até a expansão do parâmetro, resultando em uma primeira palavra dehello=hi
.Uma vez processadas as atribuições de variáveis, elas não são reprocessadas durante a execução do comando.
Veja o processamento e seus resultados em
set -x
:Para uma variação mais segura de "expansão variável" -como- "variáveis de ambiente" do que
eval
, considere a sugestão de wjandrea deenv
:Não é estritamente uma atribuição de variável de linha de comando, pois estamos usando a
env
função principal do utilitário de atribuir variáveis de ambiente a um comando, mas atinge o mesmo objetivo. A$prefix
variável é expandida durante o processamento da linha de comando, fornecendo o name=value paraenv
, que o repassa parabash
.Porque
$prefix
não é uma tarefa. @Jeff tem a explicação mais longa .Você poderia fazer uma coisa semelhante com uma função:
... e você pode até empilhá-los, se quiser: