Язык программирования shell имеет несколько конструкций, которые придадут гибкость вашим программам:
Чтобы в программе разместить комментарии, воспользуйтесь знаком #. Если знак # стоит после команды, то сама команда выполняется, а комментарий игнорируется. Формат строки комментария:
#comment
"Here document" позволяет размещать в shell программе строки, которые перенаправляются в качестве ввода команды в этой программе. Это один из способов обеспечения ввода для команды в shell программе без использования отдельного файла. Запись состоит из символа перенаправления << и разделителя, который указывает начало и конец строк ввода. В качестве разделителя может использоваться один символ или строка символов. Чаще всего это знак!.
Формат команды следующий:
Command<
"Here document" предлагает способ использования ed в shell программе. Предположим вы хотите создать shell программу, которая будет вызывать редактор ed, проводить глобальные изменения в файле, записывать изменения в файл и затем завершать работу с ed. На следующем экране приведено содержание программы ch.text, которая выполняет эти задачи:
$ cat ch.text Обратите внимание на знак - (минус)
в команде ed. Эта опция
предотвращает распечатку счетчика
символов на экране. Обратите также
внимание на формат команды ed для
глобальной замены: G/$old_text/s//$new_text/g
Программа использует 3
переменные: file1, old_text, new_text. При
запуске эта программа использует
команду read для получения значений
этих переменных. Эти переменные
содержат следующую информацию: Переменные вводятся в программу,
here document перенаправляет команду
глобальной замены, команду записи и
команду завершения команде ed.
Запустите программу ch.text. Получите
следующий экран:
$ ch.text Большинство команд shell возвращает
коды, которые указывают, успешно ли
завершилась команда. Если
возвращаемое значение 0(ноль), то
команда выполнилась успешно. Коды
возврата не печатаются
автоматически, но их можно получить
как значение специального
параметра shell $?. После выполнения в интерактивном
режиме команды, вы можете увидеть
код завершения при вводе: Рассмотрим следующий пример:
$ cat hi
This is file hi.
$ echo $?
0
$ cat hello
cat: cannot open hello
$ echo $?
2
$
В первом случае файл hi существует
в вашем справочнике и вы имеете
разрешение на чтение. С помощью
команды cat вы можете распечатать
содержимое файла. Результат
команды cat: код возврата 0, который
вы получите, задав параметр $?. Во
втором случае файл либо не
существует, либо вы не имеете право
на чтение. Команда cat печатает
диагностическое сообщение и
возвращает код 2. shell программа нормально
завершается, когда выполнится
последняя команда в файле. Однако
вы можете использовать команду exit
для завершения программы. Более
важно то, что вы можете
использовать команду exit для
получения кодов возврата shell
программы. Операторы цикла for и while позволяют
выполнить команду или
последовательность команд
несколько раз. Оператор for выполняет
последовательность команд для
каждого элемента списка. Он имеет
формат: For variable Для каждой итерации цикла
следующий элемент списка
присваивается переменной, данной в
операторе for. Ссылка на эту
переменную может быть сделана в
любом месте в командах внутри
оператора do. При конструировании
каждой секции команд вам
необходимо убедиться, что каждому do
соответствует done в конце цикла. Переменная может иметь любое имя.
Например, если ваша переменная
названа var, то ссылка в списке
команд на $var сделает значение
доступным. Если оператор in опущен,
то значением для var будет набор
аргументов, заданный в команде и
доступный в специальном параметре
$*. Список команд между ключевым
словом do и done будет выполнен для
каждого значения. Когда команды будут выполнены для
последнего элемента списка,
программа будет выполнять строку
ниже done. Оператор цикла while использует 2
группы команд. Он будет выполнять
последовательность команд во
второй группе (список do ... done) до тех
пор пока последняя команда в первой
группе (список while) возвращает
состояние "истина",
означающее, что выражение после do
может быть выполнено. Общий формат оператора цикла
while:
While Например, программа enter.name
использует цикл while для ввода
списка имен в файл. Программа
состоит из следующих командных
строк:
$ cat enter.name Внеся некоторые добавления,
получим следующую программу:
$ cat enter.name Обратите внимание, что после
завершения цикла программа
выполняет команды ниже done. В первых двух командах echo
используются специальные символы,
так что вы должны воспользоваться
кавычками для отмены специального
значения. На следующем экране
приведены результаты выполнения
программы enter.name:
$ enter.name После того, как цикл завершится,
программа распечатает все имена,
содержащиеся в xfile. Файловая система имеет файл /dev/null,
где вы можете хранить
нежелательный вывод. Например, если
просто ввести команду who, то система
ответит, кто работает в системе.
Если вы перенаправите вывод этой
команды в /dev/null: Who > /dev/null
то не получите ответа. Оператор if ... then
Команда if говорит shell программе,
что нужно выполнить
последовательность команд после
then, если последняя команда в списке
команд конструкции if выполнилась
успешно. Конструкции if
заканчиваются ключевым словом fi. Общий формат конструкции if:
If Например, shell программа search
демонстрирует применение
конструкции if ... then. Программа search
использует команду grep для поиска
слова в файле. Если grep выполнилась
успешно, то программа отображает
найденное слово. Экран будет
выглядеть следующим образом:
$ cat search Эта программа отображает вывод
команды grep. Если вы хотите
сохранить ответ системы на команду
grep в вашей программе, то
воспользуйтесь файлом /dev/null,
изменив командную строку if на
следующую: If grep $word $file > /dev/null Теперь выполните команду search. Она
ответит только сообщением,
указанным после команды echo. Конструкция if ... then ... else может
исполнять альтернативный набор
команд, стоящий после else, в случае,
если последовательность if является
ложью. Формат этой конструкции
следующий: If С помощью этой конструкции вы
можете усовершенствовать
программу search, так что она будет
сообщать вам и найденное слово и то,
что слово не найдено. В этом случае
программа search будет выглядеть
следующим образом:
$ cat search Команда test
Команда test используется для
организации цикла. Она проверяет на
истинность определенные условия и
полезна для организации условных
конструкций. Если условие истинно,
то цикл будет продолжен. Если
условие ложно, то цикл завершится и
будет выполняться следующая
команда. Некоторые примеры
использования команды test: Test -r file Пример. Создадим shell программу,
которая перемещает все исполняемые
файлы из текущего справочника в ваш
справочник bin. Для этого
воспользуемся командой test -x для
выбора исполняемых файлов.
Программа mv.file будет выглядеть
следующим образом:
$ cat mv.file Конструкция case ... esac позволяет
выбрать вам один из несколько
шаблонов и затем выполнить список
команд для этого шаблона.
Выражение-шаблон должно начинаться
с ключевого слова in, а правая
круглая скобка должна быть
помещена после последнего символа
каждого шаблона.
Последовательность команд для
каждого шаблона заканчивается
двумя знаками;;. Конструкция case
должна быть закончена ключевым
словом esac. Общий формат конструкции case:
Case word Конструкция case пытается найти word
с шаблоном pattern в первой секции
шаблонов. Если поиск удачен, то
программа выполняет командные
строки после первого шаблона до
соответствующих знаков;;. Если первый шаблон не найден, то
осуществляется переход ко второму
шаблону. Если любой шаблон найден,
то программа не рассматривает
остальные шаблоны, а переходит к
команде, следующей за esac. Знак *
используется как шаблон для поиска
любого word и таким образом дает вам
набор команд, который будет
выполнен, если никакой другой
шаблон не будет найден. Поэтому
шаблон звездочка (*) размещается как
последний шаблон в конструкции case,
чтобы другие шаблоны были
проверены первыми. Это поможет вам
обнаружить некорректный и
неожиданный ввод. В шаблонах могут использоваться
метасимволы *, ?, . Это обеспечивает
гибкость программ. Рассмотрим пример. Программа set.term
устанавливает переменную TERM в
соответствии с типом терминала,
который вы используете.
Применяется следующая командная
строка: TERM=terminal_name Шаблон * стоит последним в списке
шаблонов. Он выдает
предупреждающее сообщение, что для
указанного типа терминала нет
соответствующего шаблона и
позволяет вам завершить
конструкцию case.
$ cat set.term Команда break безусловно
останавливает выполнение любого
цикла, в котором он встречается и
передает управление команде,
следующей после ключевых слов done, fi
или esac. В предыдущем примере программы
set.term вы можете использовать
команду break, вместо echo, чтобы выйти
из программы, как приведено в
следующем примере:
$ cat set.term Команда continue приведет к тому, что
программа немедленно перейдет к
следующей итерации цикла while или for
без выполнения остальных команд в
цикле. МОСКВА 2007 Лабораторный
практикум по курсу: “Операционная
система
Red
Hat
Linux
”
Лабораторная
работа №5
Программирование
в
SHELL
Цель работы
:
на основе
ранее полученных навыков работы с
командным интерпретатором BASH
овладеть начальными навыками
программирования в командном интерпретаторе
BASH
для создания файлов сценария – SHELL
скриптов. Теоретические
сведения
Выполнение
отдельных команд в командном интерпретаторе
не всегда является эффективным средством
работы с SHELL
оболочкой. Довольно часто требуется
выполнять одни и те же последовательности
действий при работе с операционной
системой Linux
каждый месяц, каждую неделю, каждый день
и иногда и несколько раз в день. Например,
предположим, вы работаете на фирме
тестером программного обеспечения
(Test
Manager).
Каждый день вам требуется в командной
оболочке Linux
выполнять один тот набор действий, а
именно: монтирование устройства CD-ROM;
копирование всей информации с него в
папку, скажем, /opt/program
на жестком диске; демонтирование CD-ROM;
чтение файла readme
из этой папки; установка программы с
жесткого диска из папки /opt/program;
создания нового файла отчета в директории
/home/user/report_program
удаление всего содержимого дистрибутива
с жесткого диска. И это притом, что
основная ваша работа заключается в
тестировании программного обеспечения
на предмет выявления недоработок (bags).
Задача на первый взгляд простая, но
выполнять подобные действия по несколько
раз в день, притом, что вы занимаетесь
и другими делами, неудобно. Или, например,
вы работаете в фирме системным
администратором и обслуживаете около
50 компьютеров. Каждый день вам требуется
раскопировать на все компьютеры один
и тот же файл с инструкциями на текущий
день директора фирмы для всех подчиненных.
Кроме того, в ваши задачи также входит
в конце рабочего дня сохранить все
данные каждого пользователя на общем
сервере фирмы с персональных компьютеров
подчиненных. Задача также на первый
взгляд простая, но работа по набору
команд в командном интерпретаторе для
50 компьютеров займет много времени. А
если к тому же вы при наборе будите
ошибаться, например, от усталости? Данные
для директора и их владельца очень
важны, и потерять их Вам никак нельзя.
Но это еще простые действия. А представьте,
что названия файлов отчетов, название
папок с данными, имена компьютеров
каждый раз будут меняться? Что тогда
делать? Выход один – написать файл-сценария
,
т.е. создать текстовый файл, в котором
требуется описать всю последовательность
команд с путями, опциями, аргументами,
выражениями, действиями и так далее для
выполнения определенного сценария.
Например, резервирования данных. После
ввода команд в текстовый файл-сценария,
данный файл делают исполняемым или
выполняют его специальных операторов
выполнения командного интерпретатора.
Использование файлов сценария является
особенно эффективным, если вам очень
часто требуется выполнять последовательность
из большого числа команд. Также является
эффективным средством, если в зависимости
от результатов выполнения предыдущих
команд зависит выполнение следующих.
С помощью файлов-сценариев можно также
использовать арифметические и логические
выражения, создавать циклы, обеспечивающие
многократное выполнение группы команд
Linux. Создание
файлов-сценария.
Создания сценариев представляет собой
последовательный набор команд, операторов
командного интерпретатора и некоторых
других символов в текстовом файле.
Файлы-сценария также называют скриптами,
а командные интерпретаторы латинским
названием SHELL.
В связи с тем, что на сегодняшний день
существуют разные командные интерпретаторы,
написание файла-сценария с использованием
дополнительных символов, например,
метасимволов, совместно с командами не
должно противоречить правилам синтаксиса
выбранного командного интерпретатора,
в котором предполагается выполнять
данный скрипт. Процесс написания таких
файлов называют SHELL
программированием. Рассмотрим процесс
программирования на примере интерпретатора
BASH.
Таким образом, скрипты и правила написания
скриптов в данной лабораторной работе
могут быть не переносимы на другие
интерпретаторы, например, такие как С
Shell
или TC
Shell. Последовательность
#!.
Написание
любого скрипта начинается с принадлежности
его к одному из командных интерпретаторов.
В первой строке скрипта обычно пишут
последовательность #! , которая указывает
системе, какой интерпретатор должен
выполнить команды из данного сценария.
Если первый символ пробел, считается,
что сценарий написан для BASH
или PDKSH.
Если сценарий начинается только с
символа # , то для его выполнения необходим
TC
Shell.
Если же за символом # следует символ!,
ядро запустит интерпретатор, путь
которого указан далее в этой строке.
Например, для BASH
будет следующая запись: #!/bin/sh
. Пробела или одиночного символа # в
начале сценария достаточно для
интерпретаторов BASH
Shell
и TC
Shell
только при условии, что они будут
считывать свой сценарий. Чтобы один
интерпретатор распознал сценарии
другого, необходимо включать в сценарий
символы #! , после чего указывается путь
интерпретирующей программы. Тогда при
вызове сценария будет прекращена работа
текущего интерпретатора, вместо него
будет загружен сценарий другого типа,
а затем выполнен сценарий. Рекомендуется
всегда начинать все сценарии с
последовательности #! . Также строки,
начинающиеся с символа # можно использовать
для комментариев действий пользователя
в скрипте. Встретив символ #, интерпретатор
shell игнорирует эту строку. Каждый
комментарий должен завершаться символом
окончания строки. Использование
комментариев является признаком хорошего
тона. Расширение
и запуск скриптов.
Обычно файлы-сценариев имеют не только
имена, но также и расширения. Чаще всего
в качестве расширений используют
комбинацию букв sh
от латинского слова shell.
По такому расширению, не открывая файл,
сразу понятно, что это shell
скрипт, так как нам опять же понятно,
что файл с расширением .
c
скорее всего является входным файлом
языков высокого уровня С и С++. После
набора содержимого файла, файл сохраняется.
Запустить файл можно двумя способами
либо сделать его исполняемым с помощью
команды chmod,
либо запускать его с помощью специальных
операторов командного интерпретатора:
sh
и. Обычно пользователи задают для
файл-сценария восьмеричные значения
750 или 550. В следующем примере сделаем
скрипт script.sh
выполняемым с помощью команды chmod
и запустим его на выполнение из текущей
директории в фоновом режиме. chmod u+x script.sh
./
script.sh
&
Теперь вернем
файлу предыдущие атрибуты и запустим
его на выполнение с помощью оператора
BASH. chmod u-x script.sh
sh script.sh&
Команда
echo
.
Помимо перечня стандартных команд
Linux,
самое простое, что можно использовать
в скрипте – это вывод текстовых
комментариев пользователю с помощью
команда echo.
Например, данную команду можно
использоваться для приглашения
пользователя выполнить какое-нибудь
действие или использовать для приветствия
пользователя. В следующем примере с
помощью echo
отображается приветствие. echo
“Добрый день!”
Команда
read
.
При создании скриптов вы можете также
применять переменные и сценарии,
написанные для других интерпретаторов
и команд. Команда read
служит командой запроса пользователя
на ввод информации. Она сочетается с
подсказкой пользователю, которая
приглашает ввести нужную информацию.
Приведем пример использования read. echo
“Введите ваше имя: ”
read
your
_
name
echo
“
Добрый
день
,”
your_name “!”
Данный скрипт
усложнен по отношению к предыдущему.
Здесь используется переменная your_name
, значение которой потом применяется
совместно с текстом. Использование
переменных.
Как
и языках программирования, в shell
Вы также можете использовать переменные,
присваивать значения переменным можно
через оператор присваивания равно «=».
Сначала вводится имя переменной, потом
без пробела знак «=», затем без пробела
значение переменной. Имя переменной
может состоять из любого количества
буквенных символов, включая символ
подчеркивания. Имя может содержать и
цифры, однако не должно начинаться с
цифры. Все остальные символы (в частности,
восклицательный знак, амперсанд и
пробел) в имя входить не должны. Такие
символы зарезервированы интерпретатором
для специальных целей. Как следствие,
имя может состоять только из одного
слова, поскольку при синтаксическом
анализе команд интерпретатор рассматривает
пробел как разделитель имен команд и
аргументов. Значение переменной может
состоять из любой последовательности
символов. В следующем примере присвоим
переменной «ppp» значение «www123yyy». ppp
=”
www
123
yyy
”
Если вы используете
в качестве значения переменной строковое
значение, используйте двойные кавычки.
После присвоения значения вы можете
пользоваться именем переменной для
ссылки на это значение, например
использовать его в качестве аргумента
команд сценария. На значение переменной
можно ссылаться посредством ее имени,
которое предваряется оператором $. Знак
доллара - это специальный оператор,
который использует имя переменной для
ссылки на ее значение, то есть фактически
для ее вычисления. Теперь с помощью уже
знакомой команды echo
и переменной «ppp»
можно отображать значение этой переменной. echo $ppp
www123yyy
Аргументы
командной строки.
В
сценарии, как и в командах Linux,
можно использовать аргументы. Аргумент
в сценарии обозначается оператором $ с
указанием номера позиции в командной
строке. Нумерация параметров начинается
с единицы, а заканчивается девятью.
Первый
параметр задается переменной $1, второй
- $2 и т. д. Аргумент $0 резервируется
для имени shell-сценария,
в качестве которого выступает первое
слово, находящееся
в командной строке. По умолчанию имеется
возможность устанавливать 9 переменных
с $1 до $9 . Если
вводится
несколько аргументов, можно отдельно
обращаться к каждому из них по его
номеру. В следующем примере в командной
строке вводятся три аргумента.
Предварительно создадим скрипт arguments
с аргументами, а потом его выполним. Обращаем ваше
внимание, если вам требуется использовать
аргумент(ы) из нескольких слов, вы должны
в командной строке взять его (их) в
двойные кавычки. Иногда требуется задать
в сценарии точное количество аргументов,
это можно выполнить с помощью аргумента
$# . Параметр
$* позволяет указать все аргументы в
командной строке. Переменная
export.
Иногда для разных файлов-сценария
требуется воспользоваться определенной
переменной, которая уже была определена.
Переменные, которые вы определяете в
интерпретаторе shell, являются локальными
для него. В некотором смысле такая
переменная принадлежит своему
интерпретатору. Непосредственно
определить переменную для другого
интерпретатора нельзя, однако можно
экспортировать определение переменной
из одного интерпретатора в другой с
помощью команды export. Команда export содержит
инструкцию для системы, в соответствии
с которой для каждого вновь образованного
shell будет определяться копия этой
переменной. Каждый новый интерпретатор
shell будет иметь собственную копию
экспортированной переменной. В следующем
примере определим переменную «rrr» и
экспортируем ее для других интерпретаторов
с помощью команды export. Арифметические
операции – команда
let
.
Команда
let
- это команда интерпретатора BASH
shell,
обеспечивающая выполнение
операций над арифметическими величинами.
С помощью этой команды можно сравнивать
числовые значения или выполнять над
ними арифметические операции, такие
как сложение или умножение. Формат
команды:
let значение1
оператор значение2. Приведем пример. $ let 2*5
10
В
арифметические выражения, использующие
оператор let,
можно включать и операторы
присваивания. В следующем примере
результат умножения двух чисел
присваивается
переменной total. $ let “total=2*5”
$ echo $total
10
$
Операторы сравнения
часто используются для сравнения
числовых значений в управляющих
конструкциях, таких как циклы и условные
переходы. В следующем примере команды
сценария file1 четырежды выводят на экран
слово "Привет!". В данном случае
для управления выходом из цикла
используется оператор let "ttt <= 4",
а для увеличения переменной цикла again
на единицу - оператор let "ttt = ttt + 1".
Обратите внимание на то, что при изменении
переменной again ее вычислять не требуется. File1
ttt=l
while let "ttt<= 4"
do
echo $ttt Привет!
let "ttt = ttt + 1"
done
Выполнение скрипта:
$ file1
Привет!
Привет!
Привет!
Кроме того, вы
также можете использовать и другие
арифметические операторы. В таблице 1
приведены арифметические операторы и
операторы сравнения Bash
Shell. Таблица 1 -
Операторы BASH shell
Арифметические
операторы
Функции
Умножение Сложение Вычитание Деление
с остатком Операторы
сравнения
Функции
Больше
чем Меньше
чем Больше
либо равно Меньше
либо равно Равенство
в выражениях Равенство
в команде let Не
равно Логическое
И Логическое
ИЛИ Логическое
НЕ Управляющие
конструкции.
Управляющие
конструкции предназначены для управления
ходом выполнения команд
shell-сценария.
Эти конструкции позволяют организовать
повторное выполнение определенной
последовательности команд или выбирать
для выполнения команды, необходимые
в конкретной ситуации. Управляющая
конструкция состоит из двух основных
компонентов: операции проверки и команд.
В результате выполнения сравнения
(проверки
условия) возвращается значение «истина»
или «ложь», а затем на основании
полученного
результата выполняются определенные
команды. Существует
два вида управляющих конструкций:
циклические
(циклы)
и
условные
(ус
ловия).
Циклическая
конструкция используется для повторного
выполнения команд, тогда
как условная - для выполнения
последовательности команд.,
которая
удовлетворяет
определенным условиям. В интерпретаторе
BASH
shell
можно использовать три циклические
конструкции, while,
for
и for-in,
и две условные - if
и case. Управляющие
конструкции while
и if
- это конструкции общего назначения,
которые
обычно используются при решении таких
задач, как итерационные вычисления и
проверка различных условий. Управляющие
конструкции case
и for
ориентированы на
более узкий круг задач. Конструкция
case
является многовариантным оператором
и
представляет собой частный случай
условного оператора if.
Эта конструкция часто используется
при создании меню. Конструкция for
представляет собой цикл, однократно
обрабатывающий всю информацию для
каждого значения, включенного в список,
до тех пор, пока не встретится окончание
списка. Кроме
сравнения значений или переменных,
управляющие конструкции if
и while
можно
применять для проверки того, успешно
или неудачно была выполнена системная
команда Linux.
Напомним, что в Linux
каждая выполняемая команда возвращает
код завершения.
Если выполнение команды было успешным,
ее код завершения равен 0. Если
по какой-либо причине команда не была
выполнена успешно, кодом завершения
будет
некоторое положительное значение,
указывающее тип ошибки. Управляющие
конструкции
if
и while
позволяют проверить, чему был равен код
завершения: 0 или некоторому
другому значению. Если код завершения
равен нулю, значит, выполнение команды
было успешным и управляющая конструкция
if
или while
будет завершена. Команда
test
.
Сравнивать значения можно не только с
помощью условных управляющих конструкций,
но также с помощью команды test. При
сравнении двух значений test возвращает
0 в том случае, если сравнение будет
успешным. Команда test позволяет сравнивать
целые числа, строки и даже выполнять
логические операции. Совместно с
командой test применяют опции, которые
задают тип сравнения. Полный перечень
опций приведен в таблице 2. Таблица 2. Операции, выполняемые
командой test интерпретатора BASH shell
Сравнение целых
чисел
Функция
Больше
чем Меньше
чем Больше
чем либо равно Меньше
чем либо равно Не
равно Сравнение строк
Функция
Проверка
на наличие пустой строки Проверка
на наличие строкового значения Проверка
строк на равенство Прооверка
строк на неравенство Проверка
на наличие строки, состоящей из нулей Логические
операции
Функция
Логическое
И Логическое
ИЛИ Логическое
НЕ Проверка файлов
Функция
Установка
факта существования файла и его
регулярности Проверяется,
не является ли файл пустым Проверка
возможности считывания из файла Проверка
возможности записи в файл, а также его
изменения Проверяется,
является ли файл исполнимым Проверяется,
является ли имя файла именем каталога Проверяется,
является ли имя файла символической
ссылкой Проверяется,
обозначает ли имя файла байт-ориентированное
устройство Проверяется,
обозначает ли имя блок-ориентированное
устройство Команда
test
имеет следующий синтаксис: test значение -опция значение
test строка = строка
В
следующем примере покажем пример
использования команды test.
Сравним целочисленных значения, для
этого используем опцию равенства –eq.
Для проверки результата выполнения
операции сравнения используем код
завершения последней выполненной
командыtest, который
храниться в переменной $? интерпретатораshell. $
tot
=
4
$
test $
tot
-eq
7
$ echo $?
1
Также
команда test
$tot
–eq
7 может быть записана и в другом виде: $ [ $tot –eq 7 ]
Условные
конструкции:
if,
if-else, elif, case
.
Интерпретатор
BASH
shell
включает несколько условных управляющих
конструкций (табл. 3), которые позволяют
выбирать для выполнения определенные
команды Linux.
Многие из этих конструкций напоминают
условные управляющие конструкции в
языках программирования,
но имеются и некоторые отличия. Таблица
3 – Управляющие конструкции интерпретаторов
bash
Shell
Условные управляющие конструкции
Функция
if команда then команда fi Конструкция if вызывает выполнение
действия в случае, если результат
проверки истинен if команда then команда else команда fi Конструкция if-else вызывает выполнение
действия в случае, если код завершения
проверяемой команды paвен значению
«истина», в противном случае выполняется
действие else if команда then команда elif команда then
команда else команда fi Конструкция elif дает возможность
вкладывать конструкции if, что позволяет
выбрать один из многих вариантов; если
истинно условие, проверяемое первой
конструкцией if, выполняются
предусмотренные в ней команды и
следующей конструкции elif управление
не передается case строка in шаблон) команда;; еsас Конструкция case сравнивает строковое
значение с одним из нескольких шаблонов
(образцов). При обнаружении совпадения
выполняются команды, соответствующие
этому шаблону команда && команда Логическая операция И возвращает
значение 0 («истина»), если обе команды
возвращают значение 0; если же одна из
команд возвращает ненулевое значение,
результат операции И равен «ложь»
и данная операция возвращает
ненулевое значение команда | | команда Логическая операция ИЛИ, возвращающая
значение 0 («истина») в случае, если
одна или обе команды возвращают
значение 0 («истина»); если обе команды
возвращают ненулевое значение, то
результат операции ИЛИ - «ложь» и
операция возвращает ненулевое значение Команда Логическая операция НЕ, инвертирует
код завершения команды while команда do команды done Конструкция while выполняет действие
до тех пор, пока команда проверки
возвращает значение «истина» until команда do команды done Конструкция
until
выполняет действие до тех пор, пока
команда
проверки возвращает значение «ложь» Циклические управляющие конструкции
Функция while, until, for, for-in, select
for переменная in список-значений do
команды done Конструкция for-in предназначена для
обработки списка значений. Переменной
последовательно присваиваются значения
из списка for переменная do команды done Конструкция for предназначена для
последовательной обработки аргументов
сценария. Переменной последовательно
присваивается значение каждого
аргумента select строка in перечень-элементов do
команды done Конструкция select создает меню на основе
элементов заданного списка, а затем
выполняется указанная команда (обычно
это команда case) Условная
конструкция
if
-
then
.
Условная конструкция
if
ставит условие на выполнение команды.
Этим условием является код
завершения какой-то конкретной команды
Linux.
Если команда выполнена успешно (то
есть код завершения равен 0), то команды
внутри конструкции if
выполняются. Если
код завершения отличен от 0, то команды
внутри конструкции if
выполняться не
будут. Иногда требуется выбрать один
из двух вариантов, в зависимости от того
как была выполнены команда Linux.
Ключевое слово else
конструкции if
позволяет выбрать один из двух вариантов.
Приведем синтаксис команды if-then-else. Командная оболочка в любых unix-подобных системах, к которым относится и GNU/Linux, является обычной программой, запускаемой как в текстовой консоли (которая используется всё реже), так и в графической среде – в окне эмулятора терминала, доступного в любой Linux-системе. Ее задача проста и очевидна: принять строку (или строки) ввода, произвести их синтаксический анализ и на основе результатов этого анализа отреагировать соответствующим образом – выполнить команду, запустить программу, вывести диагностическое сообщение и т.п. Почти во всех дистрибутивах Linux для пользователей по умолчанию назначается командная оболочка bash (Bourne Again SHell – ещё одна командная оболочка Бурна; Стив Бурн – автор первой командной оболочки в Unix – sh). Фактически она стала неофициальным стандартом, и усовершенствование ее функциональных возможностей продолжается непрерывно. Существуют и другие командные оболочки – tcsh (версия C-shell), ksh (Korn Shell), zsh и т.д. – у каждой есть свои достоинства и недостатки, а также свои группы поклонников. Тем не менее, bash более привычна широким массам пользователей с различными уровнями подготовки, потому я и остановил свой выбор на ней. Стоит также отметить, что какими бы возможностями ни обладали различные оболочки, все они совместимы со своим идеологическим прародителем – Bourn Shell (sh). Иными словами, скрипт, написанный для sh, будет корректно работать в любой современной оболочке (обратно, вообще говоря, неверно). Может возникнуть вопрос: зачем возиться с командной строкой, если существуют удобные и красивые графические интерфейсы? Тому есть множество причин. Во-первых, далеко не все операции удобнее и быстрее выполнять с помощью графического интерфейса. Во-вторых, каждая программа следует основополагающему принципу Unix-систем: делать чётко определённую работу и делать её хорошо. Иными словами, вы всегда понимаете, что происходит при запуске той или иной утилиты (если что-то не вполне понятно, то следует обратиться к man-руководству). В-третьих, осваивая команды, пробуя их сочетания и комбинации их параметров, пользователь изучает систему, приобретая ценный практический опыт. Вы получаете доступ к таким эффективным инструментам, как конвейеры, позволяющие организовать цепочку команд для обработки данных, средства перенаправления ввода/вывода, а кроме того, можете программировать непосредственно в командной оболочке. Пожалуй, на программировании стоит остановиться подробнее, тем более что многие системные сценарии в Linux (например, скрипты запуска системных сервисов) написаны для shell. Итак, командную оболочку можно рассматривать как язык программирования и как программную среду выполнения одновременно. Разумеется, этот язык не компилируемый, а интерпретируемый. Он допускает использование переменных: системных или собственных. Последовательность выполнения команд программы изменяется с помощью конструкций проверки условия и выбора соответствующего варианта: if-then-else и case. Циклы while, until и for позволяют автоматизировать многократно повторяющиеся действия. Имеется возможность объединять группы команд в логические блоки. Вы можете даже писать настоящие функции с передачей в них параметров. Таким образом, налицо все признаки и характеристики полноценного языка программирования. Попробуем извлечь из этого двойную пользу – наряду с изучением основ программирования автоматизируем свою повседневную работу. О необходимости регулярного резервного копирования данных знают все, но у пользователей вечно не хватает времени на эту скучную операцию. Выход прост – организовать автоматическое создание резервных копий. Это и будет нашим первым заданием по программированию в командной оболочке. Любой командный сценарий (script – скрипт, так называются программы командной оболочки) начинается со строки идентификатора, в которой явно задаётся интерпретатор команд с указанием полного пути к нему. Полный путь – последовательное перечисление всех каталогов, начиная с корневого, в которые надо войти, чтобы добраться до целевого файла, и, разумеется, имя этого файла. Запись полного пути чрезвычайно важна для однозначной идентификации каждого файла в иерархии файловой системы. Далее следуют четыре строки комментариев. Как только командная оболочка встречает символ "#", она считает все последующие символы комментариями и полностью игнорирует их до конца текущей строки. Поэтому комментарий можно начать не с самого начала строки, а сопроводить им какую-либо команду. После комментариев располагается пустая строка. Для командной оболочки она ничего не значит, и никаких действий не производится. В сценариях пустые строки обычно вставляют для того, чтобы обеспечить удобство чтения программного кода. Наконец-то мы добрались до первой «настоящей» команды. Она позволяет сменить каталог (Change Directory), т.е. перейти из текущего каталога в другой, переданный команде как аргумент. В большинстве случаев целевой каталог задаётся в явной форме, например, cd /tmp или cd projects, но в нашем случае используется предопределённая системная переменная HOME – в ней содержится полный путь к домашнему каталогу текущего пользователя, от имени которого выполняется командный сценарий. Тем самым мы избавляемся от необходимости вносить изменения в код всякий раз при смене пользователя, потому что команда возвращает любого в его личный каталог. Знак доллара "$" перед именем переменной означает, что необходимо извлечь значение, содержащееся в этой переменной, и подставить его в командную строку вместо её имени. Особо следует отметить, что в командном языке оболочки регистров букв имеют важное значение, т.е. HOME, Home и home – это три различные переменные. По соглашению, буквами верхнего регистра обозначаются имена системных переменных: HOME, PATH, EDITOR и т.д. Это соглашение не запрещает пользователям создавать свои переменные с именами из заглавных букв, но зачем усложнять себе жизнь, нарушая общепринятые нормы и правила? Не рекомендуется также изменять значения системных переменных без крайней необходимости. В общем, соблюдаем простое правило: системные переменные используем только для чтения, а если потребовалась собственная, то её имя записываем буквами нижнего регистра. Нашу первую команду можно было бы записать более кратко: Здесь символ "~" также означает домашний каталог текущего пользователя. Ветераны командной строки выражаются ещё лаконичнее: Смысл в том, что когда для команды cd не задан никакой аргумент, она выполняет переход в домашний каталог. На очереди классическая программная конструкция проверки условия и принятия соответствующего решения. Общая схема такова: Последнее слово конструкции (if в обратном порядке) выполняет роль закрывающей скобки, т.е. границы списка команд, выполняемых при истинности условия. Присутствие fi обязательно, даже если в списке лишь одна команда. Для проверки условия, как правило, применяется команда test или её альтернативная форма записи в квадратных скобках. Иначе говоря, записи абсолютно равнозначны. Я предпочитаю квадратные скобки, поскольку они более наглядно определяют границы проверяемого условия. И правая, и левая скобка должны быть обязательно отделены от условия пробелами. Критерии проверки условия определяются разнообразными флагами. Команда test распознаёт очень большой их список. В нашем примере использован флаг -d, позволяющий проверить, соответствует ли заданное после флага имя реально существующему каталогу (directory). Наиболее часто при работе с файлами применяются следующие флаги: F – существует ли обычный файл с заданным именем; R – установлено ли для заданного файла право на чтение из него; W – установлено ли для заданного файла право на запись в него; X – установлено ли для заданного файла право на его выполнение; S – имеет ли заданный файл ненулевой размер. В нашем случае перед условием стоит восклицательный знак, обозначающий операцию логического отрицания, поэтому смысл проверяемого условия становится абсолютно противоположным. Попробуем записать смысл этих команд на обычном русском языке: Как видите, всё оказалось не таким уж и сложным. Немного практики, и вы без труда сможете читать и самостоятельно создавать подобные конструкции. Команда создания каталога настолько очевидна, что дополнительных разъяснений не требуется. В следующей строке мы создаём собственную локальную переменную cur_date. В подавляющем большинстве случаев переменные создаются простым присваиванием конкретного значения, например: Но в нашем примере применяется небольшая хитрость. Обратите внимание, что после знака равенства – символа присваивания – записана команда в обратных кавычках. Такая форма записи позволяет присвоить переменной не саму строку, а результат её выполнения. Здесь это вывод команды date, которая возвращает текущую дату и время в формате, определяемом списком параметров: %Y – текущий год в полной форме, т.е. из четырёх цифр (например, 2009); %m – номер текущего месяца (например, 09 – для сентября); %d – номер текущего дня; %H – текущий час в 24-часовом формате; %M – текущая минута. Таким образом, если выполнить команду десятого сентября 2009 года в 22:45, то переменной cur_date будет присвоено строковое значение "200909102245". Цель этого ухищрения – сформировать уникальное, не повторяющееся имя архивного файла. Если вы намерены запустить несколько экземпляров программы в течение одной минуты, то можете улучшить уникальность имён, добавляя ещё и текущие секунды. Как? Изучите руководство утилиты date (man date) – в этом нет ничего сложного. Прежде чем приступить к созданию файла архива, необходимо определить, какие именно каталоги мы будем сохранять в нём. Для большей гибкости можно задать набор каталогов, архивируемых по умолчанию, но предусмотреть возможность замены этого набора списком каталогов, передаваемым как аргумент в наш командный сценарий. Для этого используются специальные переменные командной оболочки: $# – число переданных в сценарий параметров и $* – все переданные параметры, записанные в формате одной строки. Проверка условия «если число переданных параметров равно нулю», то выполнить следующую команду. Отметим, что ключевое слово then можно записать в строке условия, отделив его от условного выражения точкой с запятой. Команда создания архивного файла и сжатия этого файла. Сама утилита tar не выполняет сжатие, а только лишь собирает все заданные файлы и каталоги в единый tar-файл. Для этого предназначен первый флаг - c (create – создать). Сжатие выполняет внешняя программа – здесь это gzip, вызываемый вторым флагом - z. Если в вашей системе установлена более эффективная программа сжатия bzip2, то вы можете воспользоваться ею, изменив команду следующим образом: Третий флаг f сообщает о том, что далее следует имя архивного файла, поэтому всегда является замыкающим в перечне флагов. Обратите внимание на то, что при подстановке имя переменной заключено в фигурные скобки. Это сделано, чтобы явно выделить переменную в окружающей её строке, тем самым устраняя многие потенциальные проблемы. Расширения архивному файлу не присваиваются автоматически, вы сами дописываете всё необходимое. В качестве каталогов, архивируемых по умолчанию, я указал projects и bin, но вы можете записать здесь имена своих наиболее ценных каталогов. Ключевое слово else открывает альтернативную ветвь выполнения. Команды этого блока начинают работать, если проверка условия даёт результат «ложь» (в нашем примере: «число переданных параметров ненулевое», т.е. пользователь задал имена каталогов). В этом случае команда будет выглядеть так: Здесь каталоги по умолчанию заменены строкой имён каталогов, принятой извне. Имеется возможность принимать и обрабатывать каждый внешний параметр по отдельности, но нам удобнее передать строку целиком. В конце программы выполняется ещё одна проверка. В unix-средах все команды возвращают код статуса завершения своей работы. Если команда отработала успешно, то она возвращает код 0, в противном случае код завершения будет ненулевым. Чтобы проверить успешность выполнения предыдущей команды архивации, воспользуемся ещё одной специальной переменной $?, в которой всегда содержится значение кода завершения самой последней команды. Если в переменной $? содержится 0, т.е. файл резервной копии был успешно создан, то мы перемещаем его в каталог архивов: и выдаём соответствующее сообщение: Если проверка показала, что код завершения операции архивирования не равен нулю, то выводится сообщение об ошибке: На этом работа нашего командного сценария завершается. Чтобы проверить работу нашей программы, необходимо сохранить описанный выше исходный код в файле, например, с именем bckp, а затем для удобства сделать его выполняемым: и запустить: для создания резервной копии каталогов, заданных по умолчанию, и для создания резервной копии перечисленных каталогов (укажите имена каталогов, действительно существующих в вашей системе, иначе получите сообщение об ошибке). Можно поместить файл bckp в один из каталогов, указанных в системной переменной PATH. Наиболее предпочтительными местами размещения являются /usr/local/bin или $HOME/bin, если таковые у вас имеются. После этого вы можете запускать bckp как системную команду. Несколько слов об автоматизации резервного копирования. Для этой цели служит системный планировщик cron, который считывает рабочие инструкции из специального crontab-файла. Чтобы определить такие инструкции, необходимо создать и отредактировать свой crontab-файл при помощи команды: Инструкции записываются в строго определённом формате (поля разделяются пробелами): Один из вариантов расписания операций резервного копирования может выглядеть следующим образом: Это означает, что сценарий резервного копирования (следует указать полный путь к этому файлу) будет выполняться в 23:30 10-го, 20-го и 30-го числа каждого месяца независимо от дня недели. (Звёздочки обозначают весь допустимый диапазон значений, в данном случае: каждый месяц – в 4-м поле, любой день недели – в 5-м поле) Если вы предпочитаете подводить итоги по неделям, а ваша система работает круглосуточно, то имеет смысл запланировать резервное копирование в часы с минимальной нагрузкой: Здесь резервные копии будут создаваться в 5:00 по средам и пятницам в каждом месяце (звёздочка в 4-м поле), независимо от числа (звёздочка в 3-м поле). Обо всех тонкостях составления расписания можно прочитать в руководстве man 5 crontab. Рассмотренный в данной статье сценарий резервного копирования обладает скромными функциональными свойствами. Но не в этом состояла его главная задача, а в том, чтобы читатель понял, что можно делать в командной строке, и не только скопировал и выполнил предложенный командный файл, а заинтересовался расширением его функций, занялся исследованием необъятных возможностей, предоставляемых командными оболочками. И если кто-то, прочитав эту статью, попробует усовершенствовать приведённый здесь код, или напишет собственный вариант, или реализует свою независимую идею, то я сочту, что основная цель достигнута. static.content.url=http://www.сайт/developerworks/js/artrating/ ArticleID=458335 ArticleTitle=Основы программирования в командной оболочке shell
file - имя файла, который будет
редактироваться;
old_text - текст, который будет изменен;
new_text - новый текст.9.3.4. Коды завершения
9.3.4.1. Проверка кодов завершения
9.3.5. Циклы
9.3.5.1. Оператор for
9.3.5.2. Оператор while
9.3.6. Использование /dev/null
9.3.7. Условные операторы
9.3.8. Безусловная передача
управления
Что такое shell и зачем он нужен
Преимущества командной строки
Командная оболочка в качестве языка программирования
Hello, World! Простая система резервного копирования
Как автоматизировать операции резервного копирования «по расписанию»
Итоги и выводы
Ресурсы для скачивания