¿Puedo modificar un archivo de script bash (.sh) mientras se está ejecutando?

28

Supongamos que tengo un script script.sh, que lleva algún tiempo ejecutarlo. Ejecuto, ./script.sh. Mientras se ejecuta en una ventana de terminal, modifico el archivo script.sh. ¿Tendrá algún efecto en el proceso que ya se está ejecutando?

Después de modificarlo, ejecuto el archivo modificado, por lo que ahora tengo dos procesos en ejecución. ¿Esta bien?

llamar
fuente
2
similar a unix.stackexchange.com/q/121013/55673 en U&L
Usuario registrado

Respuestas:

36

Cuando realiza cambios en su secuencia de comandos, realiza los cambios en el disco (disco duro, el almacenamiento permanente); cuando ejecuta el script, el script se carga en su memoria (RAM).

Por lo tanto, los cambios que realice en el script no afectarán al script en ejecución, ejecutará la versión que ejecutó antes de realizar esos cambios.

Sin embargo, cuando ejecute el script modificado de nuevo sin terminar la instancia que se estaba ejecutando anteriormente, habrá dos instancias del script, una que tiene los cambios y la anterior.

Tenga en cuenta que los recursos que el script usa y modifica entrarán en conflicto. Por ejemplo, si está modificando un archivo usando la secuencia de comandos, la secuencia de comandos que se ejecuta más tarde no podrá abrir ese archivo para escribir y no se ejecutará correctamente.

Actualización: Gracias al usuario registrado por indicarme una mejor respuesta en Unix.stackexchange.com.

Dependiendo del tamaño del script y del compilador / intérprete en cuestión, el script se carga parcial / completamente. Por lo tanto, si el script no está completamente cargado, los cambios que realice en su script se reflejarán en la instancia en ejecución una vez que la parte del script se cargue en la memoria.

Por lo tanto, no se recomienda cambiar su secuencia de comandos en el disco que se está ejecutando actualmente para obtener resultados impredecibles: primero detenga la instancia en ejecución y luego modifique su secuencia de comandos y luego vuelva a ejecutarla.

Jobin
fuente
11
No es la respuesta perfecta, lea unix.stackexchange.com/q/121013/55673
Usuario registrado
@registereduser: oh sí, esa pregunta me recordó mis lecciones de SO. Editaré mi respuesta tan pronto como tenga mis manos en mi escritorio (en mi teléfono en este momento)
trabajoen
Supongo que para guiones cortos no debería haber ningún problema.
Becko
1
Cuando intenté esto con bash v3.2.48 (ver aquí ), no se almacenó más allá del final de la línea (y falló gravemente cuando modifiqué el script mientras se ejecutaba). Acabo de volver a probar con bash v4.3.0, y almacenó todo el script (corto). Entonces ... no contaría con ningún comportamiento en particular.
Gordon Davisson
1
@RegisteredUser No con todas las versiones de bash; vea el ejemplo que vinculé.
Gordon Davisson
4

Agregaré algo que creo que no se ha dicho en las otras respuestas. Mucho depende de cómo edite el archivo. Hacer echo "stuff" >filedesde el shell (otra instancia) de hecho sobrescribirá el archivo, creo. Pero si edita el archivo con, por ejemplo, emacsy luego lo guarda, esto no sucederá. En cambio, aquí el editor cambia el nombre del archivo antiguo a algún nombre de copia de seguridad (tal vez en realidad elimina la copia de seguridad anterior), y luego escribe su contenido modificado del búfer como un nuevo archivo con el nombre antiguo (ahora liberado) . Dado que el intérprete de comandos (u otro intérprete) que lee el guión seguramente abrirá el archivo solo una vez, a partir de entonces es independiente del paradero del nombre del archivo, solo continúa leyendo el archivo del disco físico (identificado por el número de inodo) que estaba asociado al nombre del archivo en el momento de la apertura. Entonces, incluso si lee el script en bloques (que sería la solución más fácil si usa E / S de texto almacenado en búfer), continuaría leyendo las líneas de la instancia anterior del archivo, que es probable que no cambie con su edición.

Marc van Leeuwen
fuente
+1 Estoy usando Sublime Text como mi editor. ¿Sabes si también cambia el nombre del archivo, como emacs?
Becko
1
Creo que la mayoría de los editores usarían un esquema de cambio de nombre (incluso si no deberían mantener versiones de copia de seguridad) para evitar el riesgo de que si ocurriera un bloqueo durante el proceso de escritura, no quedaría ninguna versión intacta del texto. Puede verificar con "ls -i" (que muestra números de inodo) cuál es el comportamiento de su editor.
Marc van Leeuwen
1

esto necesita ser actualizado, las respuestas anteriores ahora son solo parcialmente correctas:

con la versión actual de bash, la modificación de una secuencia de comandos en el disco mientras se está ejecutando hará que bash "intente" cargar los cambios en la memoria y llevarlos a cabo en la secuencia de comandos en ejecución. Si sus cambios se producen después de la línea que se está ejecutando actualmente, las nuevas líneas se cargarán y ejecutarán. pero, esto es una suposición de bash y puede hacerlo bien o mal.

la mejor manera de hacer esto es la siguiente secuencia de acciones: 1) cargar la secuencia de comandos en la memoria 2) eliminar la secuencia de comandos del disco 3) escribir una nueva secuencia de comandos en el disco eliminando primero la versión del disco, la versión de la memoria pierde sus enlaces. para que cuando proporcione una nueva versión en el paso 3, bash no intente cargar los nuevos contenidos en la versión de memoria.

ivor
fuente
0

La respuesta de @ jobin es generalmente correcta, pero agregaré algunas otras respuestas que pueden ir al grano dependiendo de lo que quieras hacer.

Si desea cambiar el script y desea saber que es seguro, entonces desea escribir en un nuevo archivo, no en el existente. Sin embargo, el nuevo archivo puede ubicarse donde estaba el anterior. Escriba su nueva versión en un nuevo archivo y luego úsela mvpara colocarla sobre la parte superior de la anterior. El archivo que ha sido reemplazado todavía existe, simplemente no está vinculado desde el directorio. Su secuencia de comandos en ejecución puede continuar usándola, y cuando esa secuencia de comandos cierra su identificador de archivos, el sistema sabe que puede limpiar el archivo de forma segura (ya sea de forma inmediata o posterior).

Si quieres comportar el comportamiento del script sobre la marcha, tienes un problema más difícil. Espero que necesites incluirlo en el código del script. Las secuencias de comandos Bash pueden manejar señales (por ejemplo, pueden detectar algo parecido kill -USR1 [pid]), y una secuencia de comandos podría responder volviendo a cargar algún código. Entonces, tal vez pueda obtener una funcionalidad cercana a la que desea, pero sin saber lo que está buscando, no veo una buena razón para hacerlo, y sospecho que si desea hacer algo tan complejo, probablemente desee un sistema más sofisticado. lenguaje de programación para hacerlo.

Si quieres hackear el comportamiento de un script en ejecución que no está escrito con esto en mente, entonces no tienes suerte. Dudaría en llamar imposible cualquier tarea de programación, pero si tuviera los recursos y las habilidades para este tipo de tarea, presumiblemente no estaría preguntando aquí.

mc0e
fuente