Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Руководство по Bash для начинающих
Назад Глава 1: Командная оболочка и скрипты Bash Вперед

Разработка хороших скриптов

Особенности хороших скриптов

Данное руководство касается, главным образом, последней составляющей — скриптов. Перед тем, как продолжить, укажем на некоторые общие соображения:

  1. Скрипт должен работать без ошибок.
  2. Он должны выполнять задачу, для которой предназначен.
  3. Логика программы должна быть ясной и очевидной.
  4. Скрипт не должен делать лишней работы.
  5. Скрипт должен быть пригоден для многократного использования.

Структура

Структура скрипта является очень гибкой. Хотя Bash позволяет много чего делать, вам для того, чтобы можно было легко и правильно выполнять скрипт, требуется обеспечить корректную логику, правильную последовательность выполнения команд и должную эффективность.

Когда вы начинаете новый скрипт, задайте себе следующие вопросы:

  • Нужна ли вам какая-нибудь информация от пользователя или от используемой среды выполнения?
  • Как эта информация будет храниться?
  • Есть ли какие-нибудь файлы, которые нужно создавать? Где и с какими правами на доступ и для каких пользователей?
  • Какие команды будут использоваться? Когда скрипт используется в других системах, должны ли в них быть те же самые команды и те же самые версии команд?
  • Нужно ли о чем-либо сообщать пользователю? Когда и почему?

Терминология

В таблице, приведенной ниже, дается обзор программистских терминов, с которыми вы должны быть знакомы:

Таблица.1.1. Обзор программистских терминов

ТерминЧто означает?
Управление исполнением командПроверка кода завершения команды с тем, чтобы знать, должен ли выполнятся следующий фрагмент программы.
Условное ветвлениеЛогическое место в программе, где определяется, что будет происходить дальше
Логика программыОбщая логика программы. Определяется логическая последовательность задач, которые должны быть выполнены с тем, чтобы получить результат.
ЦиклЧасть программы, которая выполняется ноль или более раз.
Пользовательский вводИнформация, получаемая из внешнего источника в процессе работы программы, которую можно сохранить и снова использовать, когда это будет необходимо

Порядок и логика разработки скрипта

Для того чтобы ускорить процесс разработки, нужно заранее продумать логическую структуру программы. Это ваш первый шаг при разработке скрипта.

Можно использовать ряд методов; один из наиболее часто используемый — это использовать списки. Составьте список задач, с помощью которых вы сможете в программе описать все процессы. Отдельные задачи можно обозначать их порядковыми номерами.

Если вы точно опишите на естественном разговорном языке задачи, которые должны выполняться вашей программой, это поможет вам сделать вашу программу более понятной. Впоследствие вы можете заменить каждую инструкцию, записанную на естественном языке, конструкциями на языке командной оболочки.

Ниже приведен пример подобной логической схемы программы. В нем описывается ротация журнальных файлов. В этом примере показан вариант цикла, управление которым зависит от числа журнальных файлов, которые вы хотите использовать в процессе ротации:

1.	Нужна ротация журнальных файлов? 
	a.	Если "да":
		i.	Введите имя директория, в котором расположены журнальные файлы, используемые при ротации. 
		ii.	Введите базовое имя журнального файла. 
		iii.	 Укажите, сколько дней должны храниться журнальные файлы. 
		iv.	Внесите изменения в пользовательский файл crontab. 
	b.	Если "нет", перейдите к шагу 3.
2.  Вы хотите при ротации использовать другой набор журнальных файлов? 
	a.	Если "да": повторите шаг 1.
	b.	Если "нет": повторите шаг 3.
3.	Выход

Чтобы программа могла что-нибудь сделать, пользователь должен предоставить программе информацию. Нужно получить и сохранить информацию, которую вводит пользователь. Пользователь должен получить уведомление о том, что его файл crontab будет изменен.

1.5.5. Пример скрипта Bash: mysystem.sh

Скрипт mysystem.sh, приведенный ниже, выполняет несколько хорошо известных команд (date, w, uname, uptime) для того, чтобы получить информацию о вас и о вашем компьютере.

tom:~> cat -n mysystem.sh
     1  #!/bin/bash
     2  clear
     3  echo "This is information provided by mysystem.sh.  Program starts now."
     4
     5  echo "Hello, $USER"
     6  echo
     7
     8  echo "Today's date is `date`, this is week `date +"%V"`."
     9  echo
    10
    11  echo "These users are currently connected:"
    12  w | cut -d " " -f 1 - | grep -v USER | sort -u
    13  echo
    14
    15  echo "This is `uname -s` running on a `uname -m` processor."
    16  echo
    17
    18  echo "This is the uptime information:"
    19  uptime
    20  echo
    21
    22  echo "That's all folks!"

Скрипт всегда начинается с одних и тех же двух символов "#!". После них указывается командная оболочка, которая будет выполнять команды, следующие за первой строкой. Этот скрипт начинается с очистки экрана в строке 2. В строке 3 выдается сообщение, информирующее пользователя о том, что произойдет. В строке 5 выдается приветствие пользователю. Строки 6, 9, 13, 16 и 20 предназначены только для того, чтобы разграничить выдачу сообщений. В строке 8 выдается текущая дата и номер недели. В строка 11 снова выдается информационное сообщение, как и в строках 3, 18 и 22. В строке 12 задается формат выходных данных команды w; в строке 15 указывается информация об операционной системе и о процессоре. В строке 19 выполняется команда uptime и происходит загрузка информации.

Обе команды echo и printf являются встроенными командами Bash. Первая всегда завершается с кодом 0 и просто печатает аргумент, за которым при выводе в стандартный вывод следует символ конца строки, а вторая команда предназначена для задания формата строки и завершается при возникновении отказа ненулевым кодом возврата.

Вот тот же самый скрипт с использованием встроенной команды printf:

tom:~> cat mysystem.sh
#!/bin/bash
clear
printf "This is information provided by mysystem.sh.  Program starts now.\n"

printf "Hello, $USER.\n\n"

printf "Today's date is `date`, this is week `date +"%V"`.\n\n"

printf "These users are currently connected:\n"
w | cut -d " " -f 1 - | grep -v USER | sort -u
printf "\n"

printf "This is `uname -s` running on a `uname -m` processor.\n\n"

printf "This is the uptime information:\n"
uptime
printf "\n"

printf "That's all folks!\n"

Создание удобных скриптов с выдачей дополнительных информационных сообщений рассматривается в главе 8 "Пишем интерактивный скрипт".

Стандартное расположения командной оболочки Bourne Again

Подразумевается, что программа bash установлена в директории /bin.

Если отсутствует стандартный выходной поток stdout

Если вы выполняете скрипт из cron, то указывайте полные пути к именам файлов и перенаправьте выходной поток и поток сообщений об ошибках. Если вы не подумаете об этом, то поскольку оболочка работает в неинтерактивном режиме, любые сообщения об ошибках приведут к преждевременному завершению работы скрипта.

В следующих главах будут обсуждаться детали работы приведенных выше скриптов.

Пример скрипта init

Скрипт init запускает системные сервисы на машинах с UNIX и Linux. Типичными примерами являются демон системного журнала, демон управления питанием, почтовый демон и др. Эти скрипты, также известные как скрипты запуска, хранятся в конкретной месте в вашей системе, например, в директории /etc/rc.d/init.d или /etc/init.d. Начальный процесс init читает свои собственные конфигурационные файлы и решает, какие сервисы на каком уровне исполнения должны быть запущены или остановлены. Уровень исполнения предназначен для конфигурирования процессов; в каждой системе есть однопользовательский уровень исполнения, например, для выполнения административных задач, при выполнении которых система не должна выполнять каких-либо других задач, например, восстанавливать важные системные файлы из резервной копии. Также обычно есть уровни исполнения, предназначенные для перезагрузки системы и для ее остановки.

Задачи, которые должны выполняться при запуске сервиса или его остановке, перечисляются в скриптах запуска. Одной из задач системного администрирования является конфигурирование процесса init, с тем, чтобы сервисы запускались и останавливались в надлежащие моменты времени. Чтобы выполнить эту задачу, вам нужно хорошее понимание процедур запуска и остановки, используемой в вашей системе. Поэтому прежде, чем вы начнете настраивать свои собственные скрипты инициализации, мы советуем вам прочитать документацию, касающуюся init и inittab.

Ниже приведен очень простой пример скрипта, который будет выполняться при запуске и остановке вашей системы:

#!/bin/bash

# This script is for /etc/rc.d/init.d
# Link in rc3.d/S99audio-greeting and rc0.d/K01audio-greeting

case "$1" in
'start')
  cat /usr/share/audio/at_your_service.au > /dev/audio
  ;;
'stop')
  cat /usr/share/audio/oh_no_not_again.au > /dev/audio
  ;;
esac
exit 0

Инструкция case, которая часто используются в скриптах такого вида, описана в разделе "Использование инструкций exit и if"

1.5.6. Подводим итог

Bash является командной оболочкой GNU, совместимой с оболочкой Bourne и включающей в себя много полезных функций из других оболочек. Когда запускается командная оболочка, она считывает свои конфигурационные файлы. Наиболее важными из них являются следующие:

  • /etc/profile
  • ~/.bash_profile
  • ~/.bashrc

Bash ведет себя по другому, когда используется в интерактивном режиме; есть также режим, совместимый со стандартом POSIX, и режим с ограниченным доступом.

Команды, используемые в командной оболочке, можно разделить на три группы: функции оболочки, встроенные команды оболочки и команды, которые расположены в директориях вашей системы. В командной оболочке Bash поддерживает дополнительные встроенные функции, которых нет в оболочке Bourne.

Скрипты командной оболочки создаются из этих команд в соответствие с тем, как это диктуется синтаксисом командной оболочки. Скрипты читаются и исполняются построчно, и они должны иметь логическую структуру.

1.5.7. Упражнения

Предлагаемые ниже несколько упражнений подготовят вас к следующей главе:

  1. В каком месте в вашей системе расположена программа bash?
  2. Воспользуйтесь параметром --version с тем, чтобы определить, какая версия оболочки у вас работает.
  3. Какие конфигурационные файлы командной оболочки считываются в тот момент, когда вы входите в систему в графический интерфейс и открываете терминальное окно?
  4. Следующие командные оболочки являются интерактивными? Для входа в какую из них требуется вводить логин и пароль?
    • Командная оболочка открывается при помощи щелчка по полю вашего графического стола и выбора варианта "Терминал", либо то же самое, но из меню.
    • Командная оболочка, в которую вы входите с помощью команды ssh localhost.
    • Командная оболочка, в которую вы входите, когда регистрируетесь в консоле в текстовом режиме.
    • Командная оболочка, в которую можно перейти с помощью команды xterm &.
    • Командная оболочка, которая открывается с помощью скрипта mysystem.sh.
    • Командная оболочка, в которую вы входите дистанционно, причем не указываете логин и/или пароль, поскольку вы пользуетесь SSH и, возможно, ключами SSH.
  5. Можете ли вы объяснить, почему не происходит выход из bash, когда вы в командной строке набираете Ctrl + C?
  6. Покажите содержимое стека директориев.
  7. Если вы этого еще не сделали, то настройте вашу строку приглашения так, чтобы указывалось ваше месторасположение в иерархии файловой системы, например, добавив в файл ~/.bashrc следующую строку:
    export PS1="\u@\h \w> " 
    
  8. Покажите хешированные команды для вашей текущей сессии командной оболочки.
  9. Как много процессов в настоящий момент работает в вашей системе? Используйте команды ps и wc, первая строка, выдаваемая командой ps, не указывает на процесс!
  10. Как отобразить имя вашего хоста? Только имя и больше ничего!

Предыдущий раздел: Оглавление Следующий раздел:
Составляющие компоненты   Глава 2. Содержание