J'écrivais un script bash et j'ai mis à jour le code (enregistré le fichier de script sur le disque) pendant que le script attendait une entrée dans une while
boucle. Après être revenu sur le terminal et continuer avec l'appel précédent du script, bash a donné une erreur sur la syntaxe du fichier:
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
J'ai donc essayé de faire ce qui suit:
1er: créez un script, self-update.sh
appelons-le:
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
Le script lit son code, change le mot «AVANT» en «APRÈS», puis se réécrit avec le nouveau code.
2ème Run it:
chmod +x self-update.sh
./self-update.sh
3ème merveille ...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
Maintenant, je n'aurais pas deviné que sur la même invocation, il sortirait APRÈS! , sur la deuxième manche, bien sûr, mais pas sur la première.
Ma question est donc: est-ce intentionnel (par conception)? ou c'est à cause de la façon dont bash exécute le script? Ligne par ligne ou commande par commande. Y a-t-il une bonne utilisation d'un tel comportement? Un exemple?
Edit: J'ai essayé de reformater le fichier pour mettre toutes les commandes sur une seule ligne, cela ne fonctionne pas maintenant:
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;echo 'String: BEFORE.';
Production:
aularon@aularon-laptop:~$ ./self-update.sh #First invocation
String: BEFORE.
aularon@aularon-laptop:~$ ./self-update.sh #Second invocation
String: AFTER!.
Lors du déplacement de la echo
chaîne vers la ligne suivante, en la séparant de l' cp
appel rewriting ( ):
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;
echo 'String: BEFORE.';
Et maintenant ça marche à nouveau:
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.