Командный арсенал оболочки bash позволяет успешно писать простые сценарии (без этого средства автоматизации системным администраторам пришлось бы вручную вводить команды в командную строку). Ваше мастерство в использовании командных строк вы должны воплотить в искусстве создания bash-сценариев (и наоборот), что по может вам извлечь максимальную пользу из времени, потраченного на изучение оболочки bash. Но когда окажется, что ваш bash-сценарий превысил в объеме сотню строк или вам потребовались средства, которыми bash не обладает, это будет означать, что настало время переходить к языку Perl или Python.
В среде bash комментарии начинаются со знака # и продолжаются до конца строки. Как и в командной строке, вы можете разбить одну логическую строку на несколько физических строк, обозначив переход на новую строку символом обратной косой чер ты (\). И, наоборот, можно поместить на одной строке несколько операторов, разделив их точкой с запятой.
Сценарий для оболочки bash может состоять только из последовательности команд ных строк. Например, следующий сценарий helloworld просто выполняет команду echo.
В среде bash комментарии начинаются со знака # и продолжаются до конца строки. Как и в командной строке, вы можете разбить одну логическую строку на несколько физических строк, обозначив переход на новую строку символом обратной косой чер ты (\). И, наоборот, можно поместить на одной строке несколько операторов, разделив их точкой с запятой.
Сценарий для оболочки bash может состоять только из последовательности команд ных строк. Например, следующий сценарий helloworld просто выполняет команду echo.
#!/bin/bash
echo "Hello, world!"
Первая строка содержит “банальный” описательный оператор, который сообщает, что данный текстовый файл является сценарием, предназначенным для интерпретации командной оболочкой /bin/bash. При принятии решения о том, как выполнить этот файл, ядро отыщет соответствующий синтаксис. С точки зрения оболочки, “стремящей ся” выполнить этот сценарий, первая строка представляет собой просто комментарий. Если бы оболочка находилась в другом каталоге, вам пришлось бы отредактировать эту строку.
Для того чтобы подготовить этот файл к выполнению, достаточно установить его бит, “отвечающий” за выполнение (см. раздел 6.5).
$ chmod +х helloworld
$ ./helloworld3
Hello, world!
Можно также непосредственно запустить (активизировать) оболочку в качестве ин терпретатора сценария.
$ bash helloworld
Hello, world!
$ source helloworld
Hello, world!
Первая команда выполнит сценарий helloworld в новом экземпляре оболочки bash, а вторая — заставит вашу начальную оболочку прочитать содержимое файла, а затем выполнить его. Второй вариант полезен в случае, когда сценарий устанавливает переменные среды или выполняет другие операции настройки, применимые толь- ко к текущей оболочке. Обычно этот вариант используется при написании сценариев, включающих содержимое файла конфигурации, написанного в виде ряда присваиваний значений bash-переменным.4
Если вы пришли сюда из мира Windows, то вам привычно использовать понятие расширения файла, по которому можно судить о типе файла, а также о том, можно ли его выполнить. В мире UNIX и Linux признак того, может ли файл быть выполнен (и если да, то кем), содержится в специальных битах полномочий. При желании вы можете на делить свои bash-сценарии суффиксом .sh, который бы напоминал вам об их типе, но тогда при выполнении соответствующей команды вам придется вводить суффикс .sh, поскольку UNIX не интерпретирует расширения специальным образом.
От команд к сценариям
Прежде чем переходить к особенностям написания bash-сценариев, остановимся на методике этого процесса. Многие пишут bash-сценарии так же, как Perl- или Python- сценарии, т.е. используя какой-нибудь текстовый редактор. Но все же удобнее рассма тривать в качестве интерактивной среды разработки сценариев режим с приглашением на ввод команды.
Предположим, например, что у вас есть журналы регистрации, именованные с суф фиксами .log и .LOG и разбросанные по всей иерархической системе каталогов. Допустим также, что вы хотите изменить эти суффиксы, приведя их к “прописному” виду. Прежде всего, попытаемся отыскать все эти файлы.
Предположим, например, что у вас есть журналы регистрации, именованные с суф фиксами .log и .LOG и разбросанные по всей иерархической системе каталогов. Допустим также, что вы хотите изменить эти суффиксы, приведя их к “прописному” виду. Прежде всего, попытаемся отыскать все эти файлы.
$ find . -name '*log'
.do-not-touch/important.log admin.com-log/
foo.log genius/spew.log leather_flog
Так, похоже на то, что нам надо включить в шаблон точку и игнорировать при поис ке каталоги. Нажмите комбинацию клавиш <Ctrl+P>, чтобы вернуть команду в команд ную строку, а затем модифицируйте ее.
$ find .-type f -name '*.log'
.do-not-touch/important.log foo.log
Синонимом для команды source служит команда “с точкой” (dot-команда), например
. helloworld.
genius/spew.log
Ну вот, это уже выглядит лучше. Правда, каталог .do-not-touch (т.е. “не трогать”) вызывает смутное чувство опасности; но мы можем избавиться от этого неприятного хо лодка.
$ find . -type f -name '*.log ' | grep -v .do-not-touch
foo.log genius/spew.log
Теперь все в порядке: мы получили абсолютно точный список файлов, которые долж ны быть переименованы. Попробуем сгенерировать несколько новых имен.
$ find . -type f -name '*.log ' I grep -v .do-not-touch | while read fname
- do
- echo mv $ fname $ {fname/. log/. LOG/}
- done
mv genius/spew.log genius/spew.LOG
Да, это именно те команды, которые позволят переименовать нужные файлы. А как мы это делаем в реальности? Мы могли бы снова вызвать уже выполненную команду и отредактировать команду echo, чтобы заставить оболочку bash выполнять команды mv, а не просто выводить их. Ведь передача команд в отдельную копию оболочки bash — более надежный вариант работы, который к тому же требует меньшего объема редакти рования.
Нажав комбинацию клавиш <Ctrl+P>, мы обнаруживаем, что оболочка bash забот ливо свернула наш мини-сценарий в одну-единственную строку. К этой “уплотненной” командной строке мы просто добавляем канал, передающий наши выходные данные ко манде bash -х.
$ find . -type f -name '*.log ' I grep -v .do-not-touch | while read fname; do echo mv $fname $ {fname/. log/. LOG/}; done | bash -x
+ mv foo.log foo.LOG
+ mv genius/spew.log genius/spew.LOG
Ключ -x команды bash обеспечивает вывод каждой команды перед ее выполнением. Теперь мы завершили переименование файлов, но нам хотелось бы сохранить этот сценарий, чтобы можно было использовать его снова. Встроенная в bash команда fc по своему действию во многом аналогична нажатию комбинации клавиш <Ctrl+P>, но вместо возврата последней команды в командную строку она передает команду в заданный вами редактор. Добавьте в свой файл строку идентификационного комментария, поместите сохраненный файл в приемлемый для вас каталог (например, ~/bin или /usr/local/bin), сделайте файл исполняемым, и вы получите настоящий сценарий.
Итак, подытожим.
- Разрабатывайте сценарий (или его часть) в виде конвейера команд, причем поша гово и в режиме выполнения командных строк.
- Пересылайте результат в стандартный выходной поток, проверяя правильность ра боты используемых вами команд.
- На каждом этапе используйте буфер ранее выполненных команд для их появления в командной строке и инструменты редактирования — для их модификации.
- Пока вы получаете неправильные результаты, можно считать, что вы, по сути, ни чего не сделали, и до тех пор, пока команды не заработают так, как надо, ничего (из уже сделанного) не надо удалять.
- Если результат выглядит правильным, выполните команды на реальном примере, чтобы убедиться, что все получилось так, как ожидалось.
- Используйте команду fс, чтобы зафиксировать свою работу в редакторе, оформи те ее соответствующим образом и сохраните.
Источник: Unix и Linux: руководство системного администратора | Немет Эви, Снайдер Гарт 5-е издание