«99 бутылок» на баше без цикла
Когда я только начал программировать, все интерпретаторы, которые мне попадались в то далёкое время, интерпретировали программу построчно. Недавно разговаривали на эту тему с одним из приятелей, который буквально был в шоке, когда случайно обнаружил, что популярная оболочка bash работает именно таким образом.
Мне кажется совершенно естественным, что такой способ интерпретации должен дожить и до наших дней, он же очень простой в реализации и для многих вещей его вполне достаточно.
#!/bin/bash
len=$(wc -c<"$0"); : https://bolknote.ru 2021
echo -e "99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.\n"
: ${i:=99}; ((--i)) && (grep -B5 -m1 ^G "$0" |
sed "s/9[8]/$(($i-1))/g;s/9[9]/$i/g;s/ [0] / no /;s/\([1] b[^s]*\)s/\\1/g" >> "$0") ||
(echo 'No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.';truncate -s "$len" "$0")
:;Пока разговаривали, у меня возникла смешная идея — попробовать написать считалочку «99 бутылок пива…» без циклов, на принципе дописывания кода, чтобы строки добавлялись в файл программы по мере интерпретации.
Результат чуть выше. Так как bash местами довольно сложен для понимания, попробую позже (если не заленюсь) сделать разбор странно выглядящих мест этой программы отдельным постом.