В простейшем случае, скрипт — это ни что иное, как простой список команд системы, записанный в файл. Создание скриптов поможет сохранить ваше время и силы, которые тратятся на ввод последовательности команд всякий раз, когда необходимо их выполнить.
Пример 2-1. cleanup: Сценарий очистки лог-файлов в /var/log
# cleanup # Для работы сценария требуются права root. cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Лог-файлы очищены."
Здесь нет ничего необычного, это простая последовательность команд, которая может быть набрана в командной строке с консоли или в xterm. Преимущество размещения последовательности команд в скрипте состоит в том, что вам не придется всякий раз набирать эту последовательность вручную. Кроме того, скрипты легко могут быть модифицированы или обобщены для разных применений.
Пример 2-2. cleanup: Расширенная версия предыдущего сценария.
#!/bin/bash # cleanup, version 2 # Для работы сценария требуются права root. LOG_DIR=/var/log ROOT_UID=0 # Только пользователь с $UID 0 имеет привилегии root. LINES=50 # Количество сохраняемых строк по-умолчанию. E_XCD=66 # Невозможно сменить каталог? E_NOTROOT=67 # Признак отсутствия root-привилегий. if [ "$UID" -ne "$ROOT_UID" ] then echo "Для работы сценария требуются права root." exit $E_NOTROOT fi if [ -n "$1" ] # Проверка наличия аргумента командной строки. then lines=$1 else lines=$LINES # Значение по-умолчанию, если число не задано в командной строке fi # Stephane Chazelas предложил следующее, #+ для проверки корректности аргумента, переданного из командной строки, #+ правда это достаточно сложно для данного руководства. # # E_WRONGARGS=65 # Не числовой аргумент # # case "$1" in # "" ) lines=50;; # *[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $E_WRONGARGS;; # * ) lines=$1;; # esac # #* Конец проверки корректности аргумента cd $LOG_DIR if [ `pwd` != "$LOG_DIR" ] # или if [ "$PWD" != "$LOG_DIR" ] # Не в /var/log? then echo "Невозможно перейти в каталог $LOG_DIR." exit $E_XCD fi # Проверка каталога перед очисткой лог-файлов. # более эффективный вариант: # # cd /var/log || { # echo "Невозможно перейти в требуемый каталог." >&2 # exit $E_XCD; # } tail -$lines messages > mesg.temp # Сохранить последние строки в лог-файле. mv mesg.temp messages # cat /dev/null > messages #* Необходимость этой команды отпала, поскольку очистка выполняется выше. cat /dev/null > wtmp # команды ': > wtmp' и '> wtmp' имеют тот же эффект. echo "Лог-файлы очищены." exit 0 # Возвращаемое значение 0 #+ указывает на успешное завершение работы сценария.
Если вы не желаете полностью вычищать системные логи, то выше представлена улучшенная версия предыдущего сценария. Здесь сохраняются последние несколько строк (по-умолчанию — 50).
Если файл сценария начинается с последовательности #!, которая в мире Unix называется sha-bang, то это указывает системе какой интерпретатор следует использовать для исполнения сценария. Это двухбайтовая последовательность, или 1) — специальный маркер, определяющий тип сценария, в данном случае — сценарий командной оболочки (см. man magic
). Более точно, sha-bang определяет интерпретатор, который вызывается для исполнения сценария, это может быть командная оболочка (shell), иной интерпретатор или утилита. 2)
#!/bin/sh #!/bin/bash #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f #!/usr/awk -f
Каждая, из приведенных выше сигнатур, приводит к вызову различных интерпретаторов, будь то /bin/sh
— командный интерпретатор по-умолчанию (bash для Linux-систем), либо иной. 3) При переносе сценариев с сигнатурой #!/bin/sh
на другие Unix системы, где в качестве командного интерпретатора задан другой shell, вы можете лишиться некоторых особенностей, присущих bash. Поэтому такие сценарии должны быть POSIX совместимыми. 4)
Обратите внимание на то, что сигнатура должна указывать правильный путь к интерпретатору, в противном случае вы получите сообщение об ошибке — как правило это «Command not found».
Сигнатура #!
может быть опущена, если вы не используете специфичных команд. Во втором примере (см. выше) использование сигнатуры #!
обязательно, поскольку сценарий использует специфичную конструкцию присваивания значения переменной lines=50
. Еще раз замечу, что сигнатура #!/bin/sh
вызывает командный интерпретатор по-умолчанию — /bin/bash
в Linux-системах.
if [ $# -ne Number_of_expected_args ] then echo "Usage: `basename $0` whatever" exit $WRONG_ARGS fi
«Глава 1. Зачем необходимо знание языка Shell? | Часть 1. Введение | 2.1. Запуск сценария»
#! /bin/sh
.#!/bin/bash echo "Первая часть сценария." a=1 #!/bin/bash # Это *НЕ* означает запуск нового сценария. echo "Вторая часть сценария." echo $a # Значение переменной $a осталось равно 1.
#!/bin/rm # Самоуничтожающийся сценарий. # Этот скрипт ничего не делает -- только уничтожает себя. WHATEVER=65 echo "Эта строка никогда не будет напечатана." exit $WHATEVER # Не имеет смысла, поскольку работа сценария завершается не здесь.Попробуйте запустить файл
README
с сигнатурой #!/bin/more
(предварительно не забудьте сделать его исполняемым).