BASH Tips&Tricks #000B: Hello ли world? О встроенном в BASH "Эффекте бабочки".

BASH
Изучение многих языков программирования начинается с написания с простейшего кусочка кода, выводящего на экран радостно-интернациональное Hello, world!
Теперь давайте представим себе, что мы только начинаем изучать BASH и решили написать нашу первую приветствующую мир программку:

#!/bin/bash
echo "Hello, world!"

Я думаю, вы догадались уже, в чём подвох.
А именно: этот элементарный код не работает…

В ответ вы получите не приветствие, а загадочное сообщение об ошибке «event not found» или даже что-то и вовсе несуразное, от чего спасением может стать лишь судорожный Ctrl+C. Оказывается, код был не таким уж элементарным и BASH нашёл-таки, к чему придраться :)
Как с этим бороться, неужели нужно сдерживать свои эмоции и, может быть, даже сообщениями об ошибках лишь сухо констатировать факт вместо того, чтобы громко возмущаться тремя восклицательными знаками? (кстати, последнее — это очевидно дурной тон в программировании, но если очень хочется, то можно, не так ли? ;) )
Некоторые бывалые скриптописатели пользуются экранированием: "\!".
Некоторые стараются по возможности пользоваться одинарными кавычками (что правильно) или обрывать двойные кавычки и ставить одинарные как только в строке появляется пресловутый восклицательный знак: «Hello, $NAME»'!' (что в корне неверно).
Но так или иначе всё это позволяет лишь обойти проблему, не затронув её сути.
Суть же в том, что по умолчанию BASH интерполирует выражения, содержащие "!", в соответствующие им команды из истории команд. Сама по себе эта фича бывает довольно полезной, но… проблема в том, что востребованность её в неинтерактивном режиме работы BASH (проще говоря, в скриптах) асимптотически стремится к нулю.

Поэтому, собственно, мой вам совет: при написании скриптов отключайте механизм history expansion как можно раньше (оно же ASAIP).
И тогда простейшая работающая программа на BASH может выглядеть даже вот так:

#!/bin/bash
set +H
echo Hello, world!

Как нетрудно догадаться, set +H отключает интерполяцию выражений, содержащих восклицательный знак, а set -H возвращает значение «по умолчанию», т.е. включает history expansion.

Что ж, thats all i want to discuss today
Миру мир и до новых встреч! :)

2 комментария

avatar
Знаю об этой фишке с историей, но почему-то крайне редко ей пользуюсь.
Хотя довольно удобно — например почти каждый день я перестартовываю на домашнем компе одну и ту же службу:
service mediatomb restart

а можно вместо этого написать только
!ser

но я все равно пишу команду целиком… :)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.