2010-02-25 12 views
8

ACTUALIZACIÓN: esto es un repost de How to make shell scripts robust to source being changed as they run¿Puede un script de shell indicar que sus líneas se carguen en la memoria inicialmente?

Esto es un poco lo que me cada molesta de vez en cuando:

  1. escribo un script de shell (bash) para un rápido y sucio trabajo
  2. Ejecuto el script, y se ejecuta durante bastante tiempo
  3. Mientras se está ejecutando, edito unas pocas líneas en el script, configurándolo para un trabajo diferente
  4. Pero el primer proceso sigue leyendo el mismo archivo de script y obtiene todas jodido.

Al parecer, el guión se interpreta mediante la carga de cada línea del archivo que sea necesario. ¿Hay alguna manera en que pueda hacer que el guión indique al intérprete de comandos que todo el archivo del guión debe leerse en la memoria de una vez? Por ejemplo, los scripts de Perl parecen hacer esto: editar el archivo de código no afecta un proceso que actualmente lo está interpretando (¿porque se analizó/compiló inicialmente?).

Entiendo que hay muchas formas de evitar este problema. Por ejemplo, podría intentar algo como:

cat script.sh | sh 

o

sh -c "`cat script.sh`" 

... aunque los que podría no funcionar correctamente si el archivo de script es grande y hay límites en el tamaño de los búferes de secuencia y argumentos de línea de comandos. También podría escribir un contenedor auxiliar que copie un archivo de script en un archivo temporal bloqueado y luego lo ejecute, pero eso no parece muy portátil.

Así que esperaba la solución más simple que implicara modificaciones solo en el script, no en la forma en que se invoca. ¿Puedo simplemente agregar una o dos líneas al comienzo del script? No sé si existe una solución así, pero supongo que podría hacer uso de la variable $ 0 ...

+3

Este es un duplicado de http://stackoverflow.com/questions/2285403/how-to-make-shell-scripts-robust-to-source-being-changed-as-they-run – camh

+0

Gracias, camh! Esto es perfecto. – Anonymous

+0

Puede eliminar el script mientras se ejecuta, para evitar la edición. (Esto es probablemente lo que quiso decir [ephemient] (http://stackoverflow.com/users/20713/ephemient) y [Ryan Thompson] (http://stackoverflow.com/users/125921/ryan-thompson). 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

7

La mejor respuesta que he encontrado es una variación muy leve en las soluciones ofrecidas a How to make shell scripts robust to source being changed as they run. Gracias a camh por notar el repost!

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

Esto asegura que todo su código se analiza inicialmente; tenga en cuenta que la 'salida' es fundamental para garantizar que no se acceda al archivo más tarde para ver si hay líneas adicionales para interpretar. Además, como se señaló en la publicación anterior, esta no es una garantía de que otros scripts llamados por su script estén seguros.

¡Gracias a todos por la ayuda!

2

¿Qué tal una solución para la forma de editarlo?

Si el script se está ejecutando, antes de editarlo, hacer esto:

mv script script-old 
cp script-old script 
rm script-old 

Desde el torreón cáscara del archivo abierto mientras no cambie el contenido del nodo-i todo abierto funcionará bien.

Lo anterior funciona porque mv preservará el antiguo inodo mientras que cp creará uno nuevo. Como el contenido de un archivo no se eliminará en realidad si se abre, puede eliminarlo de inmediato y se limpiará una vez que el shell cierre el archivo.

+0

¡Gracias, esto es muy útil para saber! Para mí es bastante sencillo tener en cuenta, pero no la solución más ideal: sería bueno tener algo contenido en el archivo de script en sí que requiera que todo el archivo se lea a la vez. Por ejemplo, si varios desarrolladores mantienen el mismo script y puede ejecutarse durante mucho tiempo, entonces necesitaría que todos los desarrolladores se aseguraran de que hagan este truco de mv-cp-rm cada vez que editen el archivo. .. – Anonymous

+1

Ligeramente simplificado: 'cp script script-old; mv script-old script' –

+0

Simplemente puede eliminar el archivo original. Ver mi comentario a la pregunta. –

2

Utilice un editor que no modifique el archivo existente y, en su lugar, cree un archivo nuevo y luego reemplace el archivo anterior. Por ejemplo, usando :set writebackup backupcopy=no en Vim.

0

Considere la posibilidad de crear un nuevo camino de explosión para sus trabajos rápidos y sucios. Si inicia sus scripts con: #!/usr/local/fastbash

o algo así, puede escribir un contenedor fastbash que utilice uno de los métodos que mencionó.Para la portabilidad, uno puede simplemente crear un enlace simbólico de fastbash a bash, o tener un comentario en el script que indique que se puede reemplazar fastbash con bash.

0

Si usa Emacs, intente M-x customize-variable break-hardlink-on-save. Establecer esta variable le dirá a Emacs que escriba en un archivo temporal y luego cambie el nombre del archivo temporal por el original en lugar de editar el archivo original directamente. Esto debería permitir que la instancia en ejecución mantenga su versión no modificada mientras guarda la nueva versión.

Presumiblemente, otros editores semiinteligentes tendrían opciones similares.

+0

Gracias, este es un gran consejo para los usuarios de emacs, y a partir de ahora lo convertiré en mi configuración predeterminada. Pero todavía existe el problema de proteger defensivamente mi script de ejecución para que no se estropee si alguien más lo edita ... – Anonymous

+0

No funciona. Probablemente solo sea literalmente para romper enlaces duros, no para reemplazar el archivo con un nuevo guardado. –

1

De acuerdo con la documentación fiesta si en lugar de

#!/bin/bash 
body of script 

intenta

#!/bin/bash 
script=$(cat <<'SETVAR' 
body of script 
SETVAR) 
eval "$script" 

entonces creo que va a estar en el negocio.

+0

¡Gracias, Norman! Esto funciona perfectamente si se asegura de que su script termine en 'salir'. Tiene la desventaja, sin embargo, de que pierdes tu lindo formato de impresión de color en emacs ... – Anonymous

+0

¡Malditos emacs de todos modos! –

Cuestiones relacionadas