Entre las siguientes alternativas ...
con
eval
.comd="ls" eval "$comd"
con
source /dev/stdin
printf "ls" | source /dev/stdin
con
source /dev/stdin
y( )
o{ }
( printf "ls" ) | source /dev/stdin { printf "ls"; } | source /dev/stdin
(Cuando nos encontramos
printf
en{ }
, ¿hay alguna otra ventaja que no usar subnivel?)¿Cuál es la diferencia entre ellos?
¿Cuál es el preferido?
¿Cuál es la forma preferida de ejecutar comandos?
()
o{}
?
bash
command-line
MS.Kim
fuente
fuente
Respuestas:
de
bash manpage
:No hay diferencias entre las dos formas.
Solo hay una nota:
eval
concatena todos sus argumentos, que luego se ejecutan como un solo comando.source
lee el contenido de un archivo y los ejecuta.eval
solo puede construir comandos a partir de sus argumentos, nostdin
. Entonces no puedes hacer así:Su ejemplo proporciona el mismo resultado, pero el propósito de
eval
ysource
es diferente.source
generalmente se usa para proporcionar una biblioteca para otros scripts, mientraseval
que solo se usa para evaluar comandos. Debe evitar el usoeval
si es posible, porque no hay garantía de que la cuerda evadida esté limpia; debemos hacer algunos controles de cordura, utilizando en susubshell
lugar.Cuando ejecuta comandos de secuencias dentro de llaves
{ }
, todos los comandos se ejecutan en el shell actual , en lugar de un subshell (que es el caso si se ejecuta entre paréntesis (ver referencia de bash )).El uso
subshell ( )
utiliza más recursos, pero su entorno actual no se ve afectado. El uso{ }
ejecuta todos los comandos en el shell actual, por lo que su entorno se ve afectado. Dependiendo de su propósito, puede elegir uno de ellos.fuente
eval
porsource
. Supongo que la pregunta es: eseval "$cmd"
equivalente aecho "$cmd" | source /dev/stdin
. Mi opinión actual es: sí.La principal diferencia es que las formas 2 y 3 están usando una tubería, lo que obligará a bash a ejecutar el comando "fuente" en una subshell (a menos que se configure lastpipe, solo disponible en bash 4.2+), lo que lo hará bastante equivalente a :
Las consecuencias son que cualquier variable de entorno establecida por su código se perderá, por lo que esto no funcionará como se esperaba:
Para ejecutar los comandos en el shell actual, puede usar la sustitución de procesos:
Puede poner más comandos dentro de paréntesis usando punto y coma como de costumbre.
Si elimina la tubería de esta manera, creo que no hay diferencia entre usar "eval" y "source". Debe preferir el que sea más simple de usar en su caso particular:
fuente
Como complemento a las respuestas ya dadas:
Un
source
equivalente a ...... es ...
En caso de que
ls
no haya una diferencia significativa.Pero en el caso de un comando que tenga la intención de afectar su entorno actual (lo que generalmente piensa cuando usa
source
) esta variante lo haría (como su primera solución coneval
también lo haría), mientras que su segundo enfoque solo afecta el entorno de una subshell que ganó ' No estará disponible después de ejecutar su línea de código.fuente