Em um determinado shell, normalmente eu definiria uma variável ou variáveis e depois executaria um comando. Recentemente, aprendi sobre o conceito de anexar uma definição de variável a um comando:
FOO=bar somecommand someargs
Isso funciona ... mais ou menos. Não funciona quando você está alterando uma variável LC_ * (que parece afetar o comando, mas não seus argumentos, por exemplo, intervalos de caracteres '[az]') ou quando canaliza a saída para outro comando da seguinte maneira:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
Também posso acrescentar um comando2 com "FOO = bar", o que funciona, mas adiciona duplicação indesejada e não ajuda com argumentos interpretados dependendo da variável (por exemplo, '[az]').
Então, qual é uma boa maneira de fazer isso em uma única linha?
Estou pensando em algo da ordem de:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Eu tenho muitas respostas boas! O objetivo é manter essa linha única, de preferência sem usar "exportação". O método usando uma chamada para o Bash foi o melhor em geral, embora a versão entre parênteses com "exportação" fosse um pouco mais compacta. O método de usar o redirecionamento em vez de um canal também é interessante.
fonte
(T=$(date) echo $T)
funcionaráRespostas:
fonte
somecommand
como sudo, precisará passar o-E
sinalizador sudo para passar pelas variáveis. Porque variáveis podem introduzir vulnerabilidades. stackoverflow.com/a/8633575/1695680FOO_X=foox bash -c 'echo $FOO_X'
funciona conforme o esperado, mas com nomes específicos de var falha:DYLD_X=foox bash -c 'echo $DYLD_X'
echos em branco. tanto trabalho usandoeval
em vez debash -c
Que tal exportar a variável, mas apenas dentro do subshell ?:
Keith tem razão, para executar incondicionalmente os comandos, faça o seguinte:
fonte
;
ao invés de&&
; não tem comoexport FOO=bar
falhar.&&
executa o comando esquerdo, depois executa o comando direito apenas se o comando esquerdo tiver êxito.;
executa os dois comandos incondicionalmente. O lote do Windows (cmd.exe
) equivalente a;
é&
.(FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOO
yieldsFOO=XXX\nFOO=\n
.source
(aka.
) nesse caso? Além disso, os backticks não devem mais ser usados nos dias de hoje e essa é uma das razões pelas quais o uso$(command)
é muito mais seguro.bash
mas pode ser outra coisa, por exemplodash
) e não encontro problemas se precisar usar aspas dentro do comando args (someargs
).Você também pode usar
eval
:Como essa resposta com
eval
parece não agradar a todos, deixe-me esclarecer uma coisa: quando usada como escrita, com aspas simples , é perfeitamente segura. É bom, pois não inicia um processo externo (como a resposta aceita) nem executa os comandos em um subshell extra (como a outra resposta).Como obtemos algumas visualizações regulares, provavelmente é bom dar uma alternativa para
eval
isso, para agradar a todos e ter todos os benefícios (e talvez até mais!) Desse rápidoeval
"truque". Basta usar uma função! Defina uma função com todos os seus comandos:e execute-o com suas variáveis de ambiente como esta:
fonte
eval
.eval
mal sem entender o que é o maleval
. E talvez você não esteja realmente entendendo esta resposta depois de tudo (e realmente não há nada de errado com ela). No mesmo nível: você diria quels
é ruim porquefor file in $(ls)
é ruim? (e sim, você não votou na resposta aceita e também não deixou um comentário). SO é um lugar tão estranho e absurdo às vezes.eval
é mau, sem entender o que é o maleval
, estou me referindo à sua frase: Esta resposta carece de todos os avisos e explicações necessárias ao se falareval
.eval
não é ruim ou perigoso; não mais quebash -c
.eval
. Na resposta fornecida, os args foram citados de maneira única, protegendo da expansão variável, portanto, não vejo problema com a resposta.eval
é uma questão de segurança em geral (comobash -c
menos óbvia); portanto, os perigos devem ser mencionados em uma resposta que propõe seu uso. Usuários descuidados podem pegar a resposta (FOO=bar eval …
) e aplicá-la à sua situação, para que ela cause problemas. Mas, obviamente, era mais importante para o respondente descobrir se eu diminuí o voto dele e / ou outras respostas do que melhorar alguma coisa. Como escrevi antes, a justiça não deve ser a principal preocupação; não ser pior do que qualquer outra resposta dada também é independente.Use
env
.Por exemplo
env FOO=BAR command
,. Observe que as variáveis de ambiente serão restauradas / inalteradas novamente quando acommand
execução for concluída.Apenas tenha cuidado com a substituição de shell, ou seja, se você quiser fazer referência
$FOO
explicitamente na mesma linha de comando, pode ser necessário escapá-lo para que seu interpretador de shell não execute a substituição antes de executarenv
.fonte
Use um script de shell:
fonte
export
; caso contrário$FOO
, será uma variável de shell, não uma variável de ambiente e, portanto, não será visível parasomecommand
ousomecommand2
.