programa - scripts linux ejercicios resueltos
Editar shell script mientras se está ejecutando (10)
¡Buena pregunta! Espero que este simple script ayude
#!/bin/sh
echo "Waiting..."
echo "echo /"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution/" " >> ${0}
sleep 5
echo "When I was run, this was the last line"
¡Parece que en linux los cambios realizados en un .sh ejecutado son implementados por el script de ejecución, si puede escribir lo suficientemente rápido!
¿Puede editar un script de shell mientras se está ejecutando y los cambios afectan al script en ejecución?
Tengo curiosidad por el caso específico de un script csh. Tengo un lote de diferentes sabores de compilación y se ejecuta toda la noche. Si algo me ocurre a mitad de la operación, me gustaría ingresar y agregar comandos adicionales, o comentar los que no se ejecutan.
Si no es posible, ¿hay algún shell o mecanismo por lotes que me permita hacer esto?
Por supuesto que lo probé, pero pasarán horas antes de ver si funcionó o no, y siento curiosidad por lo que está sucediendo o no está sucediendo entre bastidores.
Divida su script en funciones, y cada vez que se llama a una función, usted la source
de un archivo separado. Luego, puede editar los archivos en cualquier momento y la secuencia de comandos en ejecución recogerá los cambios la próxima vez que se obtengan.
foo() {
source foo.sh
}
foo
Intenta esto ... crea un archivo llamado "bash-is-odd.sh":
#!/bin/bash
echo "echo yes i do odd things" >> bash-is-odd.sh
Eso demuestra que bash está, de hecho, interpretando el script "a medida que avanzas". De hecho, editar un script de larga duración tiene resultados impredecibles, insertar caracteres aleatorios, etc. ¿Por qué? Debido a que bash lee desde la posición del último byte, la edición cambia la ubicación del carácter actual que se está leyendo.
Bash es, en una palabra, muy, muy inseguro debido a esta "característica". svn y rsync cuando se usan con scripts de bash son particularmente problemáticos, porque por defecto "combinan" los resultados ... editando en su lugar. rsync tiene un modo que corrige esto. svn y git no lo hacen.
Os presento una solución. Crea un archivo llamado "/ bin / bashx":
#!/bin/bash
source "$1"
Ahora use #! / Bin / bashx en sus scripts y siempre ejecútelos con "bashx" en lugar de bash. Esto soluciona el problema: puede sincronizar de forma segura sus scripts.
Solución alternativa (en línea) propuesta / probada por @ AF7:
{
# your script
}
exit $?
Las llaves de rizo protegen contra las ediciones, y la salida protege contra los apéndices. Por supuesto, todos estaríamos mucho mejor si bash tuviera una opción, como ''-w'' (archivo completo), o algo que hiciera esto.
Los scripts no funcionan de esa manera; La copia en ejecución es independiente del archivo fuente que está editando. La próxima vez que se ejecute el script, se basará en la última versión guardada del archivo fuente.
Puede ser conveniente dividir este script en varios archivos y ejecutarlos individualmente. Esto reducirá el tiempo de ejecución al fallo. (es decir, divida el lote en una secuencia de comandos de compilación, ejecutando cada uno individualmente para ver cuál está causando el problema).
No escucho ... pero ¿qué pasa con algo de indirecta?
BatchRunner.sh
Command1.sh
Command2.sh
Command1.sh
runSomething
Command2.sh
runSomethingElse
Entonces deberías poder editar el contenido de cada archivo de comandos antes de que BatchRunner lo haga, ¿verdad?
O
Una versión más limpia haría que BatchRunner buscara un solo archivo donde se ejecutaría consecutivamente una línea a la vez. Entonces deberías poder editar este segundo archivo mientras el primero se ejecuta, ¿no?
No tengo instalado csh, pero
#!/bin/sh
echo Waiting...
sleep 60
echo Change didn''t happen
Ejecuta eso, edita rápidamente la última línea para leer.
echo Change happened
La salida es
Waiting...
/home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string
Hrmph.
Supongo que las ediciones de los scripts de shell no tendrán efecto hasta que se vuelvan a ejecutar.
Si todo esto está en un solo script, entonces no funcionará. Sin embargo, si lo configura como un script de controlador que llama a sub-scripts, entonces podría ser capaz de cambiar un sub-script antes de que se llame, o antes de que se vuelva a llamar si está haciendo un bucle, y en ese caso creo que esos cambios Se reflejaría en la ejecución.
Una nota al margen interesante: si está ejecutando un script de Python no cambia. (Esto es probablemente obvio para cualquiera que entienda cómo shell ejecuta los scripts de Python, pero pensó que podría ser un recordatorio útil para alguien que busca esta funcionalidad).
Yo creé:
#!/usr/bin/env python3
import time
print(''Starts'')
time.sleep(10)
print(''Finishes unchanged'')
Luego, en otra concha, mientras esto está durmiendo, edita la última línea. Cuando esto se completa, muestra la línea inalterada, presumiblemente porque está ejecutando un .pyc
? Lo mismo sucede en Ubuntu y macOS.
[editar] Véase también esta respuesta, sección 3 para soluciones provisionales.
Afecta, al menos en mi entorno, pero de una manera muy desagradable . Vea estos códigos. Primero a.sh
:
#!/bin/sh
echo "First echo"
read y
echo "$y"
echo "That''s all."
b.sh
:
#!/bin/sh
echo "First echo"
read y
echo "Inserted"
echo "$y"
# echo "That''s all."
Hacer
$ cp a.sh run.sh
$ ./run.sh
$ # open another terminal
$ cp b.sh run.sh # while ''read'' is in effect
$ # Then type "hello."
En mi caso, la salida es siempre:
hello hello That''s all. That''s all.
Esto es impredecible, por lo tanto peligroso. Ver esta respuesta, sección 3 para soluciones provisionales.
[agregado] El comportamiento exacto depende de una nueva línea adicional, y quizás también de su sabor, sistema de archivos, etc. de Unix. Si simplemente desea ver algunas influencias, simplemente agregue "echo / foo / bar" a b.sh antes y / o después la línea "leer".
por lo general, es poco común editar el script mientras se está ejecutando. Todo lo que tiene que hacer es poner en control la verificación de sus operaciones. Utilice las declaraciones if / else para verificar las condiciones. Si algo falla, entonces haz esto, o hazlo. Ese es el camino a seguir.