Новости        Телеология        en

Александр Теленьга
Любой начинающий системный администратор Linux рано или поздно сталкивается с таким понятием, как “скрипт”, будь то один из загрузочных скриптов вроде /etc/rc.d/rc или написанный разработчиком программного обеспечения скрипт конфигурирования configure. В данной статье я постараюсь показать, что написание скриптов на shell не является, чем-то из ряда вон выходящим и вполне под силу даже новичку в мире Linux.

Начнем с того, что разберем, что же скрывается за английскими терминами shell и скрипт. Shell, или оболочка, как этот термин иногда переводят – это командный интерпретатор, интерфейс между пользователем и операционной системой, её ядром. Но, кроме этого, это ещё и мощный язык программирования и написания сценариев. Он содержит свои служебные слова и управляющие конструкции и позволяет писать на нем программы. Такая программа на языке сценариев, называемая скриптом, может объединять в себе системные вызовы и команды операционной системы, а также внешние утилиты, создавая мощный инструмент для системного администрирования.

Одной из задач системного администрирования является резервное копирование важной информации. Поэтому давайте рассмотрим пример скрипта, реализующего back-up информации.

Начало начал.

Итак, прежде всего, нам необходимо разобраться в структуре скрипта. Она не представляет собой ничего сложного. По большому счету, простейший скрипт – просто перечисление системных команд. Например: echo This is just example whoami uname -a

Эти команды объединены в одном файле. Но shell должен знать, что он должен этот файл обработать, а не просто прочесть его содержимое. Для этого служит специальная конструкция: #! Эта конструкция называется «sha-bang». Вообще-то, # задает комментарий, но в данном случает sha-bang означает, что после неё пойдет путь к обработчику скрипта. Например: #!/bin/bash #!/bin/sh #!/usr/bin/perl

Мы остановимся на Bash, Bourne-Again shell. Этот shell устанавливается по умолчанию практически во всех Linux-системах, и /bin/sh ссылается на него. Об окончании скрипта говорит служебное слово exit. Вооружившись этими знаниями, напишем наш первый скрипт: #!/bin/bash echo Простой скрипт # Команда echo выводит сообщение на экран echo Вы: whoami # whoami показывает имя зарегистрированного пользователя echo Ваша система стартовала uptime # uptime показывает время включения машины echo Сегодня date # date показывает текущую дату и время echo Пока все exit Сохраним этот файл под именем tutor1.sh. Выполним команду chmod +rx tutor1.sh, чтобы сделать скрипт исполняемым.

Результатом выполнения скрипта будет: voland@superstar:~/Doc/Open Source$ ./tutor1.sh Простой скрипт Вы: voland Ваша система стартовала 14:38:46 up 1:48, 2 users, load average: 0.47, 0.43, 0.41 Сегодня Вск Фев 26 14:38:46 MSK 2006 Пока все

Переходим к более серьезному.

Теперь, когда мы научились писать простейшие скрипты, самое время перейти к серьезным вещам: написанию скрипта для резервного копирования.
Перво-наперво, необходимо определить – резервную копию чего мы будем делать. Поэтому наш скрипт должен уметь работать с командной строкой. Аргументы командной строки задаются после имени скрипта через пробел: somescript arg1 arg2 arg3. Скрипт воспринимает аргументы по номерам их следования, поэтому мы будем использовать конструкции вида $номер_аргумента, т.е. $1, $2, $3. $ - это символ подстановки, который нам понадобится и при работе с переменными. Переменные в скрипте задаются в виде имя_переменной=значение. Мы будем использовать переменные MAXPARAMS для определения максимального количества параметров командной строки, BACKUPFILE для задания имени архива, BACKUPDIR для папки, резервную копию которой мы будем делать и ARCHIVEDIR для папки, куда мы поместим архив. Самой главной частью скрипта будут команды поиска и архивации всех найденных файлов и папок в указанной: find . -type f -print0 | xargs -0 tar rvf "$archive.tar" > /dev/null gzip $archive.tar Давайте разберемся, что же эти команды делают. find ищет в текущем каталоге - об этом говорит первый аргумент "." - все файлы и выдает полный путь к ним - print0. Эти пути перенаправляюся команде tar, которая собирает все файлы в один. Затем командой gzip мы архивируем получившийся tar-файл. Команда > /dev/null удобна, если вы архивируете большое количество файлов. В этом случае их имена и полный путь к ним не выводятся на консоль. Следующий шаг должен предусмотреть подсказки пользователю, как пользоваться скриптом, если он допустит какие-то ошибки. Например, эта конструкция if [ $# -lt "$MAXPARAMS" ]; then echo echo "Использование: sh `basename $0` имя_архива папка-источник папка-назначение" echo exit 0 fi подскажет, что пользователь указал недостаточное количество аргументов командной строки. If [условие]...fi задает условную конструкцию. $# -lt "$MAXPARAMS" проверяет введенное количество параметров и, если это число окажется меньше MAXPARAMS, то пользователю будет выдано сообщение об ошибочном вводе. exit 0 заставит скрипт прекратить работу без указания кода ошибки. Аналогично проверяется превышение допустимого числа параметров, только вместо ls [less then – меньше, чем], необходимо указать gt [greater then - больше, чем]. Теперь, когда основные моменты скрипта разъяснены, можно переходить к полной его версии: #!/bin/bash # Описание: #+ Делает резервную копию всех файлов в указанной директории #+ в "tarball" (архив tar.gz). #+ Использование: #+ sh backup.sh имя_архива папка-источник папка-назначение #+ Автор: #+ Александр "Voland" Теленьга # Максимальное количество параметров командной строки MAXPARAMS=3 if [ $# -lt "$MAXPARAMS" ]; then echo echo "Использование: sh `basename $0` имя_архива папка-источник папка-назначение" echo exit 0 fi if [ $# -gt "$MAXPARAMS" ]; then echo echo "Для этого скрипта нужно только $MAXPARAMS аргументов командной строки!" echo exit 0 fi # Переменные, которые мы используем в скрипте BACKUPFILE=$1-backup-$(date +%m-%d-%Y) archive=$BACKUPFILE BACKUPDIR=$2 ARCHIVEDIR=$3 # Проверяем, есть ли папка-источник и папка-назначение if [ ! -e $BACKUPDIR ]; then echo echo "\"$BACKUPDIR\" не существует!" echo exit 0 fi if [ ! -e $ARCHIVEDIR ]; then echo echo "\"$ARCHIVEDIR\" не существует, создаем..." mkdir $ARCHIVEDIR echo "Готово." fi # Проверяем, есть ли архивы в источнике и назначении. cd $ARCHIVEDIR if [ -e $archive.tar.gz ]; then rm $archive.tar.gz fi cd $BACKUPDIR if [ -e $archive.tar.gz ]; then rm $archive.tar.gz fi # Главная часть скрипта... echo "Делаем резервную копию \"$BACKUPDIR\" в файл \"$archive.tar.gz\"..." find . -type f -print0 | xargs -0 tar rvf "$archive.tar" > /dev/null gzip $archive.tar echo "\"$BACKUPDIR\" была успешно заархивирована в файл \"$archive.tar.gz\"." # Перемещаем архив в папку ARCHIVEDIR echo "Перемещаем архив \"$archive.tar.gz\" в папку \"$ARCHIVEDIR\"." mv $archive.tar.gz $ARCHIVEDIR/$archive.tar.gz echo "Готово." exit 0

Надеюсь, основные моменты я прокомментировал достаточно подробно. Если у вас возникли какие-либо вопросы, то вы можете связаться со мной по адресу. Рекомендую также замечательную книгу "Advanced Bash-Scripting Guide" Менделя Купера [Mendel Cooper], которая очень помогла мне в свое время, когда я только знакомился со скриптами. Удачного программирования.

2001-2024 Лицензия CC BY-NC-ND Денис Полевой