165 votos

comando eval en Bash y sus usos típicos

Después de leer el bash páginas de comando man y con respecto a este post.

Todavía estoy teniendo problemas para entender lo que exactamente el eval comando hace y que serían sus aplicaciones típicas. Por ejemplo, si hacemos:

bash$ set -- one two three  # sets $1 $2 $3
bash$ echo $1
one
bash$ n=1
bash$ echo ${$n}       ## First attempt to echo $1 using brackets fails
bash: ${$n}: bad substitution
bash$ echo $($n)       ## Second attempt to echo $1 using parentheses fails
bash: 1: command not found
bash$ eval echo \${$n} ## Third attempt to echo $1 using 'eval' succeeds
one

¿Exactamente lo que está pasando y cómo haga el signo de dólar y la barra invertida en el problema?

196voto

Gilles Puntos 37537

eval toma una cadena como argumento y la evalúa como si la hubiera escrito esa cadena de caracteres en una línea de comandos. (Si se pasa varios argumentos, en primer lugar se unió con espacios entre ellos.)

${$n} es un error de sintaxis en bash. Dentro de las llaves, sólo puede tener un nombre de variable, con algunas posibles prefijo y sufijo, pero usted no puede tener arbitraria de la sintaxis de bash y, en particular, no se puede utilizar la variable de expansión. Hay una manera de decir "el valor de la variable cuyo nombre es en esta variable", a pesar de que:

echo ${!n}
one

$(…) ejecuta el comando especificado en el interior de los paréntesis en una subshell (es decir, en un proceso independiente que se hereda todos los ajustes, tales como valores de las variables de la shell actual), y reúne a su salida. Así, echo $($n) corre $n como un comando de la shell, y muestra su salida. Desde $n evalúa 1, $($n) intenta ejecutar el comando 1, que no existe.

eval echo \${$n} ejecuta los parámetros pasados a eval. Después de la expansión, los parámetros son echo y ${1}. Así, eval echo \${$n} ejecuta el comando echo ${1}.

Tenga en cuenta que la mayoría de las veces, usted debe usar comillas dobles alrededor de sustituciones de variables y comandos susbtitutions (es decir, en cualquier momento hay un $): "$foo", "$(foo)". Siempre ponga comillas alrededor de variable y comando de sustituciones, a menos que usted sabe que usted necesita para dejarlos. Sin las comillas, el shell realiza la división de campo (es decir, se divide el valor de la variable o la salida del comando en separar las palabras) y, a continuación, trata a cada palabra como un patrón de caracteres comodín. Por ejemplo:

$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *

eval no se utiliza muy a menudo. En algunas de las conchas, el uso más común es para obtener el valor de una variable cuyo nombre no se conoce hasta el tiempo de ejecución. En bash, esto no es necesario gracias a la ${!VAR} de sintaxis. eval todavía es útil cuando usted necesita para construir más de comando que contiene operadores, palabras reservadas, etc.

39voto

Hari Shankar Puntos 9405

Basta pensar eval como "la evaluación de su expresión una vez más antes de la ejecución"

eval echo \${$n} se convierte echo $1 después de la primera ronda de evaluación. Tres cambios al aviso:

  • La \$ se convirtió $ (de La barra invertida es necesaria, de lo contrario se intenta evaluar ${$n}, lo que significa que una variable denominada {$n}, lo cual no está permitido)
  • $n fue evaluado 1
  • La eval desaparecidos

En la segunda ronda, es básicamente echo $1 que puede ser ejecutado directamente.

Así, eval <some command> evaluará primero <some command> (por evaluar aquí me refiero a sustituir las variables, reemplazar caracteres de escape con los correctos, etc.), y, a continuación, ejecute la expresión resultante, una vez más.

eval se utiliza cuando se desea crear dinámicamente las variables, ni leer los resultados de programas específicamente diseñados para ser leídos como este. Ver http://mywiki.wooledge.org/BashFAQ/048 para los ejemplos. El enlace también contiene algunas formas típicas en que eval se utiliza, y los riesgos asociados a ella.

25voto

sootsnoot Puntos 354

En mi experiencia, un "típico" uso de eval es para ejecutar los comandos que generan los comandos del shell para configurar las variables de entorno.

Tal vez usted tiene un sistema que utiliza un conjunto de variables de entorno, y usted tiene un script o programa que determina que se debe establecer y sus valores. Cada vez que se ejecuta un script o programa, que se ejecuta en una horquilla de proceso, por lo que nada se hace directamente a las variables de entorno se pierde cuando sale de la misma. Pero ese script o programa puede enviar los comandos de exportación a stdout.

Sin eval, tendría que redirigir stdout a un archivo temporal, el origen de la temp archivo y, a continuación, elimínelo. Con eval, usted puede:

eval $(script-or-program)

10voto

Nikhil Gupta Puntos 19

La instrucción eval dice la cáscara a las discusiones de eval tomar como comando y ejecutarlas a través de la línea de comandos. Es útil en una situación como abajo:

En la secuencia de comandos si está definiendo un comando en una variable y más adelante desea utilizar ese comando, deberá utilizar eval:

/home/user1 > a="ls | more"
/home/user1 > $a
bash: command not found: ls | more
/home/user1 > # Above command didn't work as ls tried to list file with name pipe (|) and more. But these files are not there
/home/user1 > eval $a
file.txt
mailids
remote_cmd.sh
sample.txt
tmp
/home/user1 >

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X