Сценарии оболочки. Как?
Создание пользовательского сценария -- просто, как правда. Для этого всего и нужно:
- создать командную конструкцию, достойную увековечивания;
- поместить ее в простой текстовый файл;
- по потребности и желанию снабдить комментариями;
- тем или иным способом запустить файл на исполнение.
С принципами создания команд и командных конструкций мы в первом приближении разобрались (или пытались разобраться) раньше. А вот способов помещения их в файл существует множество. Можно просто ввести (или вызвать из буфера истории) нужную команду и оформить ее как аргумент команды echo
, вывод которой перенаправить в файл:
$ echo "cp -rf workdir backupdir" > mybackup
Таким образом мы получили простейший скрипт для копирования файлов из рабочего каталога в каталог для резервного хранения данных, что впредь и будем проделывать регулярно (не так ли?).
Аналогичную процедуру можно выполнить с помощью команды cat
-- она, оказывается, способна не только к объединению файлов и выводу их содержимого, но и к вводу в файл каких-либо данных. Делается это так. Вызываем cat
с перенаправлением ее вывода в файл:
$ cat > myarchive
и нажимаем Enter. После этого команда остается в ожидании ввода данных для помещения их в новообразованный файл. Не обманем ее ожиданий и проделаем это. Причем можно не жаться и выполнить ввод в несколько строк, например:
cd $HOME/archivedir tar cf archive.tar ../workdir gzip archive.tar
Завершив ввод тела скрипта, все той же клавишей Enter открываем новую строку и набираем комбинацию Control+D, выдающую символ окончания файла.
В результате получаем сценарий для архивирования в специально предназначенном для этого каталоге archivedir
наших рабочих данных (командой tar
), а заодно и их компрессии (командой gzip
) -- в Unix, в отличие от DOS/Windows, архивирование и компрессия обычно рассматриваются как разные процедуры.
Наконец, сценарий можно создать в любом текстовом редакторе. но это не так интересно -- по крайней мере, пока. Да и стоит ли вызывать редактор ради двух-трёх строк?
Комментариями в шелл-сценариях считаются любые строки, начинающиеся с символа решетки (#
) -- они не учитываются интерпретатором и не принимаются к исполнению. Хотя комментарий может быть начат и внутри строки -- важно только, что между символом #
и концом её больше ничего не было бы. Ясно, что комментарии -- элемент для скрипта не обязательный, но очень желательный. Хотя бы для того, чтобы не забыть, ради чего этот сценарий создавался.
Но одна строка, начинающаяся символом решётки, в сценарии практически обязательна. И должна она быть первой и выглядеть следующим образом:
#!/path/shell_name
В данном случае восклицательный знак подчеркивает, что предваряющий его символ решетки (#
) -- не комментарий, а указание (т.н. sha-bang) на точный абсолютный путь к исполняемому файлу оболочки, для которой наш сценарий предназначен, например,
#!/bin/sh
для POSIX-шелла, или
#!/bin/bash
для оболочки bash
. Здесь следует подчеркнуть, что шелл, для которого предназначается сценарий, отнюдь не обязан совпадать с командной оболочкой пользователя. И полноты картины для замечу, что указание точного имени интерпретатора требуется не только для шелл-скриптов, но и для программ на любых языках сценариев (типа Perl или Python).
Так что по хорошему в обоих приведенных выше примерах ввод команд сценария следовало бы предварить строкой sha-bang. Конечно, отсутствие имени командной оболочки в явном виде обычно не помешает исполнению шелл-сценария -- для этого будет вызван командный интерпретатор по умолчанию, то есть /bin/sh
во FreeBSD или /bin/bash
в Linux (файл /bin/sh
, который обязан присутствовать в любой POSIX-системе, в Linux представляет собой символическую ссылку на /bin/bash
и предназначен для имитации POSIX-шелла).
Однако если сценарий предназначен для другой командной оболочки, то без sha-bang он может исполняться неправильно (а если оболочка еще и не из семейства совместимых с POSIX shell -- то не исполняться вообще).
К слову сказать, если вписать строку sha-bang лениво -- то следует еще и воздержаться от комментария в первой строке: в некоторых случаях он может быть интерпретирован как вызов конкретной оболочки (в частности, csh
или tcsh
). Лучше оставить первую строку свободной или начать сценарий с "пустой" команды :
, не совершающей никакого действия.
Теперь остается только выполнить наш сценарий. Сделать это можно разными способами. Самый напрашивающийся -- непосредственно вызвать требуемый шелл как обычную команду, снабдив его аргументом -- именем сценария (предположим, что он находится в текущем каталоге):
$ bash scriptname
Далее, для вызова скриптов существует специальная встроенная команда оболочки, обозначаемая символом точки. Используется она аналогично:
$ . ./scriptname
с тем только исключением, что тут требуется указание текущего каталога в явном виде (что и символизируется ./
).
Однако наиболее употребимый способ запуска сценариев -- это присвоение его файлу так называемого атрибута исполнения. Что это такое, с чем этот атрибут едят и как присваивают, будет темой отдельного разговора. Здесь же только отметим, что присвоение атрибута (или, как ещё говорят, бита) исполнения -- это процедура, которая волшебным образом превращает невзрачный текстовый файлишко во всамделишную (хотя и очень простую) программу.
Так вот, после присвоения нашему сценарию бита исполнения запустить его можно точно также, как любую другую команду -- просто из командной строки:
$ ./scriptname
Опять же -- в предположении, что сценарий находится в текущем каталоге (./
), иначе потребуется указание полного пути к нему. Что, понятно, лениво, но решается раз и навсегда: все сценарии помещаются в специально отведенный для этого каталог (например, $HOME/bin
), который и добавляется в качестве еще одного значения переменной PATH
данного пользователя (о чём говорилось здесь ).