Entre as seguintes alternativas ...
com
eval
.comd="ls" eval "$comd"
com
source /dev/stdin
printf "ls" | source /dev/stdin
com
source /dev/stdin
e( )
ou{ }
( printf "ls" ) | source /dev/stdin { printf "ls"; } | source /dev/stdin
(Quando corremos
printf
em{ }
, há algum benefício além de não usar subnível?)Qual a diferença entre eles?
Qual é o preferido?
Qual é a maneira preferida de executar comandos?
()
ou{}
?
bash
command-line
MS.Kim
fonte
fonte
Respostas:
de
bash manpage
:Não há diferenças entre as duas maneiras.
Há apenas uma nota:
eval
concatenou todos os seus argumentos, que são executados como um único comando.source
lê o conteúdo de um arquivo e os executa.eval
só pode criar comandos a partir de seus argumentos, nãostdin
. Então você não pode fazer assim:Seu exemplo fornece o mesmo resultado, mas o objetivo
eval
esource
é diferente.source
é geralmente usado para fornecer uma biblioteca para outros scripts, enquantoeval
é usado apenas para avaliar comandos. Você deve evitar o uso,eval
se possível, porque não há garantia de que a cadeia avaliada esteja limpa; devemos fazer algumas verificações de sanidade, usando em seusubshell
lugar.Quando você executa comandos de sequência dentro de chaves
{ }
, todos os comandos são executados no shell atual , em vez de um subshell (que é o caso se você executar entre parênteses (consulte a referência do bash )).O uso
subshell ( )
usa mais recursos, mas seu ambiente atual não é afetado. O uso{ }
executa todos os comandos no shell atual, para que seu ambiente seja afetado. Dependendo do seu objetivo, você pode escolher um deles.fonte
eval
porsource
. Eu acho que a pergunta é: éeval "$cmd"
equivalente aecho "$cmd" | source /dev/stdin
. Minha opinião atual é: sim.A principal diferença é que o 2º e o 3º formulários estão usando um canal, o que forçará o bash a executar o comando "source" em um subshell (a menos que lastpipe esteja definido, disponível apenas no bash 4.2+), o que o tornará praticamente equivalente a :
As conseqüências são que quaisquer variáveis de ambiente definidas pelo seu código serão perdidas, portanto isso não funcionará conforme o esperado:
Para executar os comandos no shell atual, você pode usar a substituição de processo:
Você pode colocar mais comandos entre parênteses usando ponto e vírgula, como de costume.
Se você eliminar o pipe dessa maneira, acredito que não há diferença entre usar "eval" e "source". Você deve preferir o que é mais simples de usar no seu caso particular:
fonte
Como complemento às respostas já dadas:
Um
source
equivalente a ...... é ...
No caso de
ls
não haver diferença significativa.Porém, no caso de um comando que pretenda afetar seu ambiente atual (o que você normalmente pretende usar
source
), essa variante o faria (como sua primeira soluçãoeval
também faria), enquanto sua segunda abordagem afeta apenas o ambiente de um subshell que ganhou ' Não esteja disponível após a execução da sua linha de código.fonte