GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo leer todo el script de Shell antes de ejecutarlo?

Por lo general, si edita un script, todos los usos en ejecución del script son propensos a errores.

Según tengo entendido, bash (¿otros shells también?) Lee el script de forma incremental, por lo que si modificaste el archivo del script externamente, comienza a leer cosas incorrectas. ¿Hay alguna forma de prevenirlo?

Ejemplo:

sleep 20

echo test

Si ejecuta este script, bash leerá la primera línea (digamos 10 bytes) y se irá a dormir. Cuando se reanuda, puede haber diferentes contenidos en el script a partir del décimo byte. Puede que esté en medio de una línea en el nuevo guión. Por lo tanto, el script en ejecución se romperá.

Respuesta aceptada:

Sí, conchas y bash en particular, tenga cuidado de leer el archivo una línea a la vez, para que funcione igual que cuando lo usa de forma interactiva.

Notarás que cuando el archivo no se puede buscar (como una canalización), bash incluso lee un byte a la vez para asegurarse de no leer más allá del \n personaje. Cuando se puede buscar el archivo, se optimiza leyendo bloques completos a la vez, pero vuelve a buscar después del \n .

Eso significa que puedes hacer cosas como:

bash << \EOF
read var
var's content
echo "$var"
EOF

O escriba scripts que se actualicen solos. Cosa que no podrías hacer si no te diera esa garantía.

Ahora, es raro que desee hacer cosas como esa y, como descubrió, esa característica tiende a ser un estorbo más a menudo de lo que es útil.

Para evitarlo, puede intentar y asegurarse de no modificar el archivo en el lugar (por ejemplo, modificar una copia y mover la copia en su lugar (como sed -i o perl -pi y algunos editores lo hacen, por ejemplo)).

O podrías escribir tu guión como:

{
  sleep 20
  echo test
}; exit

(tenga en cuenta que es importante que exit estar en la misma línea que }; aunque también podrías ponerlo dentro de las llaves justo antes del cierre).

o:

main() {
  sleep 20
  echo test
}
main "[email protected]"; exit

El shell necesitará leer el script hasta que exit antes de empezar a hacer nada. Eso asegura que el shell no volverá a leer el script.

Sin embargo, eso significa que todo el script se almacenará en la memoria.

Eso también puede afectar el análisis del script.

Por ejemplo, en bash :

export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'

Daría salida a ese U+00E9 codificado en UTF-8. Sin embargo, si lo cambia a:

{
  export LC_ALL=fr_FR.UTF-8
  echo $'St\ue9phane'
}

El \ue9 se expandirá en el conjunto de caracteres que estaba en vigor en el momento en que se analizó el comando, que en este caso es antes la export se ejecuta el comando.

Relacionado:SSH:¿script para automatizar scp en la red?

También tenga en cuenta que si la source también conocido como . se usa el comando, con algunos shells, tendrá el mismo tipo de problema para los archivos fuente.

Ese no es el caso de bash aunque cuyo source El comando lee el archivo completamente antes de interpretarlo. Si escribe para bash específicamente, podría hacer uso de eso agregando al comienzo del script:

if [[ ! $already_sourced ]]; then
  already_sourced=1
  source "$0"; exit
fi

(Sin embargo, no confiaría en eso, ya que puedes imaginar futuras versiones de bash podría cambiar ese comportamiento que actualmente se puede ver como una limitación (bash y AT&T ksh son los únicos shells similares a POSIX que se comportan así hasta donde puedo decir) y el already_sourced el truco es un poco frágil ya que asume que la variable no está en el entorno, sin mencionar que afecta el contenido de la variable BASH_SOURCE)


Linux
  1. ¿Cómo obtener la dirección IP externa en un script de Shell?

  2. ¿Cómo depurar un script Bash?

  3. ¿Cómo cifrar o hacer que el script de Shell sea ilegible?

  4. ¿El propósito de .bashrc y cómo funciona?

  5. ¿Cómo detener el script Loop Bash en la terminal?

Cómo usar el comando de lectura Bash

Cómo ejecutar un script Bash

¿Cómo sé el nombre del archivo de script en un script Bash?

¿Cómo ejecutar un script de shell en una consola Unix o terminal Mac?

¿Cómo leer la penúltima línea en un archivo usando Bash?

Shell Script, lea en la misma línea después de hacer eco de un mensaje