¿Eval $ (nombre de archivo de gato) es lo mismo que el nombre de archivo de origen?

9

Trabajando en algunas funciones de bash, no conocía el source ...comando, así que usé en su eval $(cat ...)lugar. Ahora me pregunto, ¿cuándo debería cambiar cada uso de eso, o es simplemente la misma función?

Parecen funcionar igual ahora, pero tal vez habrá algunas diferencias engañosas más tarde, solo quiero saber.

Benjamín
fuente

Respuestas:

6

eval $(cat ...)No funciona en todos los casos. Por ejemplo, los saltos de línea se convierten en un solo espacio $(cat ...)antes de que el contenido sea procesado por eval. Esto a menudo rompe declaraciones de varias líneas como bucles y documentos aquí.

Pruebe, por ejemplo, el siguiente archivo con ambos métodos:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Florian Diesch
fuente
44
Si usa comillas, el espacio en blanco permanecerá intacto:eval "$(cat file)"
Glenn Jackman
1
Sí, eso también debería funcionar. Pero si uno tiene que cambiar el código de todos modos, prefiero sourceya que es un comando hecho específicamente para esto.
Florian Diesch
9

Como ya lo mencionó @glennjackman, querrás citar la sustitución del comando; de lo contrario, la división de palabras y la expansión del nombre de ruta modificarán el contenido antes de que se evada. Y aunque ambos ejecutarán los comandos del archivo, hay diferencias.

  • Cuando la fuente de un guión, diversas variables especiales de shell serán modificados, sobre todo el BASH_SOURCE, BASH_LINENOy FUNCNAMEmatrices. Estos son útiles para imprimir mensajes de error y depuración.

  • Puede regresar de un script de origen con el returncomando ( help return). Con la evaluación, no obtendrá ese efecto. Y de manera similar, no se activará una trampa de RETORNO para la evaluación.

  • Al buscar un script, puede pasarle argumentos. No puedes hacer eso con esa evaluación.

  • Con la evaluación, la sustitución del comando leerá todo el contenido del archivo en la memoria antes de pasarlo a evaluación. Cuando lo obtengas, bash leerá el archivo a medida que avanza.

geirha
fuente
1

Hay un buen resumen de lo que hacen la fuente, eval y exec aquí: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Creo que su uso de eval y la fuente del archivo hará lo mismo. Sin embargo, no estoy completamente seguro de que las variables dentro del subíndice se comporten igual en cualquier caso. Recomendaría usar la fuente si es posible, porque es la forma más sencilla de hacerlo y hace que su código sea más legible.

Hinz
fuente
3
completamente tangencial: bash tiene una abreviatura de $(cat file)->$(< file)
glenn jackman