Stavo scrivendo uno script bash e mi è capitato di aggiornare il codice (salvato il file dello script su disco) mentre lo script era in attesa di alcuni input in un while
ciclo. Dopo essere tornato al terminale e aver continuato con la precedente chiamata dello script, bash ha dato un errore sulla sintassi del file:
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
Quindi ho provato a fare quanto segue:
1 °: crea uno script, self-update.sh
chiamiamolo:
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
Quello che fa lo script è leggere il suo codice, cambiare la parola "PRIMA" in "DOPO", quindi riscriverlo con il nuovo codice.
2 Eseguilo:
chmod +x self-update.sh
./self-update.sh
3a meraviglia ...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
Ora, non avrei immaginato che sulla stessa invocazione avrebbe prodotto DOPO! , nella seconda manche di sicuro, ma non nella prima.
Quindi la mia domanda è: è intenzionale (in base alla progettazione)? o è a causa del modo in cui bash esegue lo script? Riga per riga o comando per comando. C'è un buon uso di tale comportamento? Qualche esempio di esso?
Modifica: ho provato a riformattare il file per mettere tutti i comandi in una riga, non funziona ora:
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;echo 'String: BEFORE.';
Produzione:
aularon@aularon-laptop:~$ ./self-update.sh #First invocation
String: BEFORE.
aularon@aularon-laptop:~$ ./self-update.sh #Second invocation
String: AFTER!.
Mentre si sposta la echo
stringa sulla riga successiva, separandola dalla cp
chiamata rewriting ( ):
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;
echo 'String: BEFORE.';
E ora funziona di nuovo:
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.