2010-02-18 6 views
10

¿Han notado las personas que si modifica el origen de un script de shell, las instancias que se están ejecutando actualmente pueden fallar?Cómo hacer que los scripts de shell robustos a la fuente se cambien a medida que se ejecutan

Esto en mi opinión es muy malo; significa que tengo que asegurarme de que todas las instancias de un script se detengan antes de realizar cambios. Mi comportamiento preferido sería que las secuencias de comandos existentes continúen ejecutándose con el código fuente anterior y que las nuevas instancias usen el nuevo código (por ejemplo, qué ocurre con los programas de Perl y Python).

¿La gente tiene alguna buena solución para este comportamiento, que no sea copiar previamente el script de shell a un archivo temporal y ejecutarlo desde allí?

Gracias, /YGA

+0

También puede eliminar la secuencia de comandos mientras se ejecuta, para evitar su edición. Ver [esta publicación] (http://stackoverflow.com/questions/8335747/emacs-workflow-to-edit-bash-scripts-while-they-run) por el motivo y cómo automatizarlo. –

Respuesta

16

muy ligero, además de las otras respuestas a continuación:

#!/bin/sh 
{ 
    # Your stuff goes here 
    exit 
} 

El exit al final es importante. De lo contrario, aún se puede acceder al archivo de script al final para ver si hay más líneas para interpretar.

Esta pregunta fue luego vuelto a publicar aquí: Can a shell script indicate that its lines be loaded into memory initially?

+1

La solución de Jonathan Leffler es buena, pero no funcionaba para mí sin la salida :-) – YGA

2

Asegúrese de que la cubierta tiene que analizar todo el archivo antes de ejecutar cualquiera de él:

#!/bin/ksh 
{ 
all the original script here 
} 

Eso hace el truco.

Incidentalmente, con Perl (y supongo que Python), el programa analiza el archivo completo antes de ejecutar cualquiera de ellos, exactamente como se recomienda aquí. Por eso no suele encontrarse con el problema con Perl o Python.

+0

Este código tiene un defecto. Ver la [respuesta del usuario "anónimo"] (http://stackoverflow.com/a/2358432/780703). –

2

El comportamiento deseado puede no ser posible, dependiendo de la complejidad de los scripts de shell que estén involucrados.

Si la secuencia de comandos completa está contenida en un único archivo fuente, y ese archivo se analiza completamente antes de la ejecución, entonces la secuencia de comandos generalmente está a salvo de modificaciones en la copia en el disco durante la ejecución. Envolver todos los enunciados ejecutables en una función (o serie de funciones) generalmente logrará el objetivo que busca.

#!/bin/sh 

doit() 
{ 
# Stuff goes here 
} 
# Main 
doit 

La dificultad viene cuando la secuencia de comandos shell "incluye" otras secuencias de comandos shell (por ejemplo, "", o "fuente"). Si estos includes están envueltos en una función, no se analizarán hasta que se llegue a esa declaración en el flujo de ejecución. Esto hace que el script de shell sea vulnerable a los cambios en ese código externo.

Además, si el script de shell ejecuta cualquier programa externo (por ejemplo, script de shell, programa compilado, etc.), ese resultado no se captura hasta que se alcanza ese punto en la ejecución (si es que lo hace).

#!/bin/sh 

doit() 
{ 
    if [[some_condition]] ; then 
     resultone=$(external_program) 
    fi 
} 
# Main 
doit 
+0

Tu código debe considerarse pseudocódigo para 'sh'. –

Cuestiones relacionadas