Saltar al contenido

Comando eval en Bash y sus usos típicos

Después de consultar con especialistas en esta materia, programadores de diversas áreas y maestros dimos con la respuesta al dilema y la plasmamos en esta publicación.

Solución:

eval toma una string como su argumento, y lo evalúa como si hubieras escrito eso string en una línea de comando. (Si pasa varios argumentos, primero se unen con espacios entre ellos).

$$n es un error de sintaxis en bash. Dentro de las llaves, solo puede tener un nombre de variable, con algunos posibles prefix y sufijos, pero no puede tener una sintaxis bash arbitraria y, en particular, no puede usar la expansión variable. Sin embargo, hay una manera de decir “el valor de la variable cuyo nombre está en esta variable”:

echo $!n
one

$(…) ejecuta el comando especificado entre paréntesis en una subcapa (es decir, en un proceso separado que hereda todas las configuraciones, como los valores de las variables, de la capa actual) y recopila su salida. Entonces echo $($n) carreras $n como un comando de shell y muestra su salida. Ya que $n evalúa a 1, $($n) intentos de ejecutar el comando 1que 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. Entonces eval echo $$n ejecuta el comando echo $1.

Tenga en cuenta que la mayoría de las veces, debe usar comillas dobles alrededor de las sustituciones de variables y sustituciones de comandos (es decir, cada vez que hay una $): "$foo", "$(foo)". Siempre ponga comillas dobles alrededor de las sustituciones de variables y comandos, a menos que sepa que necesita dejarlos fuera. Sin las comillas dobles, el shell realiza la división de campos (es decir, divide el valor de la variable o la salida del comando en palabras separadas) y luego trata cada palabra como un patrón 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 usa muy a menudo. En algunos shells, el uso más común es 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 sintaxis. eval sigue siendo útil cuando necesita construir un comando más largo que contenga operadores, palabras reservadas, etc.

Simplemente piense en eval como “evaluar 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 a notar:

  • los $ se convirtió $ (La barra invertida es necesaria, de lo contrario, intenta evaluar $$nlo que significa una variable llamada $nque no está permitido)
  • $n fue evaluado a 1
  • los eval desaparecido

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

Entonces eval primero evaluará (por evaluar aquí me refiero a sustituir variables, reemplazar caracteres escapados con los correctos, etc.), y luego ejecutar la expresión resultante una vez más.

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

En mi experiencia, un uso “típico” de eval es para ejecutar comandos que generan comandos de shell para establecer variables de entorno.

Tal vez tenga un sistema que use una colección de variables de entorno y tenga un script o programa que determine cuáles deben establecerse y sus valores. Cada vez que ejecuta un script o programa, se ejecuta en un proceso bifurcado, por lo que todo lo que hace directamente a las variables de entorno se pierde cuando sale. Pero ese script o programa puede enviar los comandos de exportación a stdout.

Sin eval, necesitaría redirigir stdout a un archivo temporal, generar el archivo temporal y luego eliminarlo. Con eval, puedes simplemente:

eval "$(script-or-program)"

Tenga en cuenta que las citas son importantes. Tome este ejemplo (ideal):

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

Te mostramos comentarios y valoraciones

Si haces scroll puedes encontrar las notas de otros administradores, tú de igual forma tienes la libertad de mostrar el tuyo si dominas el tema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *