Para esta pregunta, consideremos un script de shell bash, aunque esta pregunta debe ser aplicable a todos los tipos de script de shell.
Cuando alguien ejecuta un script de shell, ¿Linux carga todo el script a la vez (tal vez en la memoria) o lee los comandos del script uno por uno (línea por línea)?
En otras palabras, si ejecuto un script de shell y lo elimino antes de que se complete la ejecución, ¿finalizará la ejecución o continuará como está?
linux
shell
shell-script
usuario registrado
fuente
fuente
Respuestas:
Si lo usa
strace
, puede ver cómo se ejecuta un script de shell cuando se ejecuta.Ejemplo
Digamos que tengo este script de shell.
Ejecutándolo usando
strace
:Echar un vistazo dentro del
strace.log
archivo revela lo siguiente.Una vez que el archivo ha sido leído, se ejecuta:
En lo anterior, podemos ver claramente que todo el script parece estar siendo leído como una sola entidad y luego ejecutado allí. Por lo tanto, "aparecerá" al menos en el caso de Bash en el que lee el archivo y luego lo ejecuta. ¿Crees que podrías editar el script mientras se está ejecutando?
NOTA: ¡no lo hagas! Siga leyendo para comprender por qué no debe meterse con un archivo de script en ejecución.
¿Qué pasa con otros intérpretes?
Pero tu pregunta está un poco fuera de lugar. No es Linux el que necesariamente carga el contenido del archivo, es el intérprete el que carga el contenido, por lo que depende realmente de cómo el intérprete implemente si carga el archivo por completo o en bloques o líneas a la vez.
Entonces, ¿por qué no podemos editar el archivo?
Sin embargo, si usa un script mucho más grande, notará que la prueba anterior es un poco engañosa. De hecho, la mayoría de los intérpretes cargan sus archivos en bloques. Esto es bastante estándar con muchas de las herramientas de Unix donde cargan bloques de un archivo, lo procesan y luego cargan otro bloque. Puede ver este comportamiento con estas preguntas y respuestas de U&L que escribí hace un tiempo sobre
grep
, tituladas: ¿Cuánto texto consume grep / egrep cada vez? .Ejemplo
Digamos que hacemos el siguiente script de shell.
Resultando en este archivo:
Que contiene el siguiente tipo de contenido:
Ahora, cuando ejecute esto utilizando la misma técnica anterior con
strace
:Notarás que el archivo se está leyendo en incrementos de 8 KB, por lo que Bash y otros shells probablemente no cargarán un archivo en su totalidad, sino que los leerán en bloques.
Referencias
fuente
Esto depende más del shell que del sistema operativo.
Dependiendo de la versión,
ksh
lea el script a pedido por bloque de 8k o 64k bytes.bash
lea el guión línea por línea. Sin embargo, dado que las líneas de hecho pueden ser de longitud arbitraria, se lee cada vez 8176 bytes desde el comienzo de la siguiente línea para analizar.Esto es para construcciones simples, es decir, un conjunto de comandos simples.
Si se utilizan comandos estructurados de shell ( un caso que la respuesta aceptada no se tiene en cuenta ) como un
for/do/done
bucle, uncase/esac
interruptor, un documento aquí, un subshell entre paréntesis, una definición de función, etc. y cualquier combinación de lo anterior, los intérpretes de shell se leen hasta el final de la construcción para asegurarse primero de que no haya un error de sintaxis.Esto es algo ineficiente ya que el mismo código puede leerse una y otra vez una gran cantidad de veces, pero mitigado por el hecho de que este contenido normalmente se almacena en caché.
Cualquiera que sea el intérprete de shell, es muy imprudente modificar un script de shell mientras se ejecuta, ya que el shell es libre de leer nuevamente cualquier parte del script y esto puede conducir a errores de sintaxis inesperados si no está sincronizado.
Tenga en cuenta también que bash podría bloquearse con una violación de segmentación cuando no puede almacenar una construcción de script demasiado grande, ksh93 puede leer sin problemas.
fuente
Eso depende de cómo funciona el intérprete que ejecuta el script. Todo lo que hace el núcleo es notar que el archivo a ejecutar comienza
#!
, esencialmente ejecuta el resto de la línea como un programa y le da el ejecutable como argumento. Si el intérprete enumerado allí lee ese archivo línea por línea (como hacen los shells interactivos con lo que escribe), eso es lo que obtiene (pero las estructuras de bucle de varias líneas se leen y se guardan para que se repitan); si el intérprete extrae el archivo en la memoria, lo procesa (tal vez lo compila en una representación intermedia, como lo hacen Perl y Pyton), el archivo se lee por completo antes de ejecutarse.Si elimina el archivo mientras tanto, el archivo no se elimina hasta que el intérprete lo cierre (como siempre, los archivos desaparecen cuando la última referencia, ya sea una entrada de directorio o un proceso que lo mantiene abierto) desaparece.
fuente
El archivo 'x':
La carrera:
IIRC un archivo no se elimina mientras un proceso lo mantenga abierto. La eliminación solo elimina el DIRENT dado.
fuente