Я писал сценарий bash и случайно обновил код (сохранил файл сценария на диске), пока сценарий ожидал некоторого ввода в while
цикле. После того, как я вернулся в терминал и продолжил предыдущий вызов скрипта, bash выдал ошибку о синтаксисе файла:
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
Поэтому я попытался сделать следующее:
1-й: создайте скрипт, self-update.sh
давайте назовем его:
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
Сценарий читает код, изменяя слово «ДО» на «ПОСЛЕ», а затем переписывает себя с новым кодом.
2-ой Запустите это:
chmod +x self-update.sh
./self-update.sh
3-е чудо ...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
Я бы даже не догадался, что при одном и том же вызове он выдаст ПОСЛЕ! На втором запуске точно, но не на первом.
Итак, мой вопрос: это намеренно (по замыслу)? или это из-за того, как bash запускает скрипт? Строка за строкой или команда за командой. Есть ли польза от такого поведения? Любой пример этого?
Редактировать: я попытался переформатировать файл, чтобы поместить все команды в одну строку, он не работает сейчас:
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;echo 'String: BEFORE.';
Вывод:
aularon@aularon-laptop:~$ ./self-update.sh #First invocation
String: BEFORE.
aularon@aularon-laptop:~$ ./self-update.sh #Second invocation
String: AFTER!.
При перемещении echo
строки на следующую строку, отделив ее от cp
вызова rewriting ( ):
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;
echo 'String: BEFORE.';
И теперь это работает снова:
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.