Estaba escribiendo un script bash, y se me ocurrió actualizar el código (guardé el archivo del script en el disco) mientras el script esperaba alguna entrada en un while
bucle. Después de regresar al terminal y continuar con la invocación previa del script, bash dio un error sobre la sintaxis del archivo:
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
Entonces intenté hacer lo siguiente:
Primero: crea un script, self-update.sh
llamémoslo:
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
Lo que hace el script es leer su código, cambiar la palabra 'ANTES' a 'DESPUÉS', luego reescribirse con el nuevo código.
2º Ejecutarlo:
chmod +x self-update.sh
./self-update.sh
Tercera maravilla ...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
¡Ahora, no habría adivinado que en la misma invocación saldría DESPUÉS! , en la segunda carrera seguro, pero no en la primera.
Entonces mi pregunta es: ¿es intencional (por diseño)? o es por la forma en que bash ejecuta el script? Línea por línea o comando por comando. ¿Hay algún buen uso de tal comportamiento? ¿Algún ejemplo de ello?
Editar: intenté formatear el archivo para poner todos los comandos en una línea, no funciona ahora:
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;echo 'String: BEFORE.';
Salida:
aularon@aularon-laptop:~$ ./self-update.sh #First invocation
String: BEFORE.
aularon@aularon-laptop:~$ ./self-update.sh #Second invocation
String: AFTER!.
Mientras mueve la echo
cadena a la siguiente línea, separándola de la cp
llamada rewriting ( ):
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;
echo 'String: BEFORE.';
Y ahora funciona de nuevo:
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.