Файл: Учебнометодическое пособие Томск 2016 2 удк 004. 451(075. 8) Ббк 32. 973. 2018. 2я73 к 754 Рецензенты.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 07.11.2023
Просмотров: 349
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
57 батывающие программы, зная лишь имя соответствующего исполняемого фай- ла. Речь идет об интерпретаторе команд ОС.
2.5 Язык управления операционной системой
2.5.1 Общие сведения
Любая операционная система предоставляет своему пользователю (поль- зователям) возможность управлять своей работой. Поэтому язык управления
ОС является обязательной частью интерфейса между пользователем и ВС. Су- ществуют два основных типа таких языков.
Первый тип языка управления ОС ориентирован на работу системы с не- подготовленным пользователем и заключается в использовании меню: в любой момент времени пользователь видит на экране набор доступных команд, из ко- торых он должен сделать выбор. Такой подход реализован в различных Win- dows. В этих системах используется графическое меню: на экране представле- ны значки, соответствующие исполняемым файлам, файлам данных, а также каталогам (папкам). Пользователь сообщает о своем выборе в «меню», наведя курсор мыши, а затем нажав на ее клавишу. При выборе исполняемого файла
(расширение имени файла – com, exe или bat) ОС запускает на выполнение соответствующую программу или программы (для bat-файла). Выбор файла данных означает, что на исполнение должна быть запущена системная утилита, выполняющая обработку данного файла. Выбор каталога приводит к выводу на экран меню, состоящего из файлов и подкаталогов этого каталога.
Второй тип языков управления ОС – языки команд. Каждый такой язык ориентирован на подготовленного пользователя, знакомого с языком команд.
Набрав на клавиатуре свою команду, пользователь нажимает клавишу
Любой из подходов к организации пользовательского интерфейса пред- полагает, что обработку команд управления ОС выполняет ее модуль, называе- мый интерпретатором команд ОС (сокращенно ИК). Как и любой интерпрета- тор, данная программа выполняет обработку поступающих на ее вход команд по одной, запуская на выполнение требуемую машинную программу или под- программу. Являясь для пользователя частью ОС, ИК рассматривается основ- ной частью этой системы (ядром ОС) как обычная обрабатывающая программа.
58
Следствием этого является то, что ИК размещается в отдельном исполняемом файле. Для MS-DOS это command.com, а в любой UNIX-системе существует несколько взаимозаменяемых ИК. Наиболее известные из них: Bourne shell
– файл /bin/sh, C shell – /bin/csh, Korn shell – /bin/ksh,
Bourne-Again shell – /bin/bash. Все эти ИК имеют общее название – shell
. В качестве примера далее рассматривается язык команд для наиболее типичного shell – Bourne shell.
После входа пользователя в систему и запуска первоначального shell
(эти операции будут рассмотрены в п. 4.1) на экран выводится приглашение ввести следующую команду. Часто в качестве такого приглашения использует- ся символ «$». В ответ пользователь набирает команду одного из следующих типов:
1) простая команда;
2) составная команда;
3) вызов подпрограммы на языке shell;
4) управляющий оператор;
5) командный файл.
Пользователи-непрограммисты обычно ограничиваются первыми двумя типами команд, так как применение остальных типов команд фактически озна- чает программирование на языке команд shell.
2.5.2 Простые команды
Простые команды shellделятся на команды: а) запуска программ; б) команды вызова функций shell; в) вспомогательные команды. Последняя из перечисленных групп команд будет рассмотрена нами в пп. 2.5.4 при рас- смотрении переменных shell.
Первые две группы команд, которые мы будем сейчас рассматривать, различаются по реализации: команда запуска программы требует от shell обеспечить выполнение какой-то обрабатывающей программы (прикладной, утилиты или лингвистического процессора), а команда вызова функции shell запускает внутреннюю подпрограмму самого shell. С точки зрения пользова- теля ВС эти два типа команд почти не различимы. Единственное различие: ко- манда запуска программы имеет, а команда вызова функции shell не имеет кода завершения. Код завершения – целое неотрицательное число: 0 – запу-
59 щенная программа завершилась успешно; > 0 – программа завершилась с ошибкой.
Так как число исполняемых файлов практически не ограничено, то и не ограничено число простых команд запуска программ. По своей форме наиболее распространенная команда shell представляет собой имя исполняемого файла прикладной или системной обрабатывающей программы, за которым через раз- делитель (символ пробела) записаны параметры команды. Пример команды:
$ cat abc.txt.
Эта команда выведет на экран содержимое файла abc.txt. Это – наибо- лее простое задание исполняемого файла, но любой ИК, в том числе и shell, позволяет задавать дополнительные условия выполнения запускаемой про- граммы, существенно помогающие пользователю ВС в изложении требуемой ему задачи. Рассмотрим способы указания таких условий.
Использование метасимволов. Оно позволяет пользователю существенно сократить число набираемых имен файлов. Основные метасимволы:
1) * – соответствует любой последовательности символов, в том числе и пустой, кроме последовательностей, начинающихся с символа «.»;
2) ? – соответствует любому одиночному символу;
3) [...] – соответствует любому одиночному символу из тех, что пере- числены без разделяющих символов в квадратных скобках. Пара сим- волов, разделенных символом «–», соответствует одиночному симво- лу, код которого попадает в диапазон между кодами указанных символов, включая их самих.
Для самих запускаемых программ метасимволы shell «незаметны», так как shell подставляет вместо имен, использующих их, обычные имена фай- лов. Например, пусть пользователь набрал последовательность команд (напом- ним, что утилита ls без параметров выводит на экран содержимое текущего каталога):
$ ls client client.c server.c
$ cc *.c
Тогда действительный вызов транслятора cc, выполняемый shell, име- ет вид: cc client.c server.c.
60
Перенаправление ввода-вывода. Оно позволяет пользователю в удобной форме выполнить замену файлов, используемых в качестве стандартного ввода и стандартного вывода запускаемой программы. Напомним, что по умолчанию стандартным вводом является клавиатура, а стандартным выводом – экран. По умолчанию экран используется также в качестве второго выходного файла, в который выводятся сообщения об ошибках. Перечислим операции перена- правления ввода-вывода:
1) > файл – программа выполняет вывод данных не на экран, а в задан- ный файл, начиная с его начала. Если файл с таким именем уже суще- ствует, то его прежнее содержимое будет уничтожено. Если файл не существует, то он будет создан;
2) >> файл – программа добавляет свои выходные данные в конец су- ществующего файла. Если файла не было, то он создается;
3) < файл – программа выполняет ввод данных не с клавиатуры, а из заданного файла;
4) << слово – программа выполняет ввод данных с клавиатуры до тех пор, пока в этих данных не встретится заданное слово или не будет введен символ конца файла (<Ctrl>&<D>).
Подобно использованию метасимволов, сама запускаемая программа ни- чего «не знает» об используемых в команде операциях перенаправления ввода- вывода. Дело в том, что программа обращается к экрану и клавиатуре не по их пользовательским именам (именам соответствующих файлов), а использует для этого программные имена файлов: клавиатура – 0; экран – 1; экран для вывода ошибок – 2. Поэтому обработка операции перенаправления ввода-вывода в ИК заключается в том, что прежде чем будет запущена требуемая программа, ИК откроет под номерами 0, 1, 2 не клавиатуру и экран, а файлы, указанные в пользовательской команде.
В следующих примерах операции перенаправления ввода-вывода демон- стрируются на примере утилиты cat.
1. $ cat > abc.txt
В этом примере cat используется в качестве простейшего текстового ре- дактора, который позволяет вводить текст, строка за строкой, с клавиатуры в файлabc.txt, начиная с его начала. Каждая введенная строка может быть сразу же отредактирована. Ввод символов заканчивается символом конца файла
(<Ctrl>&<D>).
61 2. $ cat >> abc.txt
Отличие этого примера от предыдущего в том, что вводимые с клавиату- ры символы добавляются в конец файлаabc.txt.
3. $ cat < abc.txt
Эта команда выводит на экран содержимое файлаabc.txt. Точно такого же эффекта можно достичь и командой:$ cat abc.txt. Разница в том, что в первом случае запускаемая утилитаcat не получает никаких параметров, а во втором случае таким параметром является имя файлаabc.txt.
4. $ cat << ! > abc.txt
Ввод с клавиатуры помещается в файл abc.txtдо тех пор, пока не бу- дет введен символ «!». В этом примере и в следующем используются сразу две операции перенаправления ввода-вывода.
5. $ cat < xy.txt > abc.txt
Эта команда выполняет копирование файлаxy.txtв файлabc.txt. То есть эта команда является некоторым аналогом команды cp.
Так как системные утилиты выводят свои сообщения об ошибках на экран, то эти сообщения иногда мешают восприятию с экрана другой информа- ции и тем самым раздражают пользователя. Для подавления таких сообщений их перенаправляют с экрана в другой файл, например в файл с именем
/dev/null
. Этот файл соответствует псевдоустройству, вывод в который означает уничтожение выводимой информации. Сама операция перенаправле- ния сообщений об ошибках аналогична перенаправлению стандартного вывода с тем лишь отличием, что слева от операции «>» или «>>» записывается цифра
«2» – программное имя файла, предназначенного для вывода ошибок.
Например, следующие две команды выводят на экран содержимое всех текстовых файлов, содержащихся в текущем каталоге: а) cat./*; б) саt./* 2>/dev/null.
Программа cat, запущенная первой из этих команд, выводит на экран свое «ругательство» по поводу каждого нетекстового файла или подкаталога.
Второй запуск этой программы выводит на экран лишь содержимое текстовых файлов.
Запуск исполняемого файла в фоновом режиме. Если запускаемая про- грамма использует клавиатуру и (или) экран, то она относится к запускающему ее ИК логически так же, как относится подпрограмма к запускающей ее про-
62 грамме. То есть так как ИК не может выполняться без экрана и клавиатуры, ко- торые существуют для конкретного пользователя в единственном экземпляре, то до завершения запущенной программы ИК будет «без движения». При этом говорят, что программа запускается в оперативном режиме.
Если программе не нужны ни клавиатура, ни экран, то ее можно запу- стить в фоновом режиме. Это означает, что после запуска программы она и ИК выполняются асинхронно (независимо). (На самом деле, как будет показано в следующих разделах, ИК может выполнять некоторые действия по управле- нию запущенной программой, но эти действия не являются обязательными и зависят от желания пользователя.)
Для запуска исполняемого файла в фоновом режиме достаточно в конце команды записать символ «&». Например, следующая команда выполняет в фоновом режиме копирование поддерева файловой структуры с корнем dir1 в поддерево с корнем dir2:
$ cp -r dir1 dir2 &.
1 2 3 4 5 6 7 8 9 ... 23
2.5.3 Составные команды
В отличие от простой команды составная команда позволяет пользовате- лю запустить не один, а несколько исполняемых файлов. Такая команда пред- ставляет собой или конвейер, или командный список, или многоуровневую ко- манду.
Конвейер программ. Имена исполняемых файлов, образующих конвейер, разделяются символом «|». Стандартный вывод программы, стоящей слева от этого символа, одновременно является стандартным вводом для программы, записанной справа. Пример конвейера:
$ find dir1 -name a1 | cat > file.
В этом примере утилитаfind выводит список файлов с простым именем a1
, находящихся в поддереве файловой структуры с корнемdir1(это подка- талог текущего каталога). Причем вывод осуществляется не на экран, а в файл на диске, из которого утилитаcat переписывает имена файлов в файлfile.
Программы, образующие конвейер, не конкурируют между собой из-за экрана и клавиатуры, так как клавиатура может быть нужна только первой, а экран – только последней программе конвейера. Поэтому эти программы за- пускаются shellодновременно (асинхронно). После запуска программы, рас- положенные по соседству в конвейере, взаимодействуют между собой через
63 промежуточный файл следующим образом. Программа, для которой этот файл является выходным, помещает в него свои данные построчно (в приведенном примере каждая строка содержит имя файла). Другая программа считывает эти данные также построчно, не дожидаясь завершения работы первой программы.
Заметим, что несмотря на то, что промежуточный файл реально существует на диске, его имя неизвестно для пользователя, которому, впрочем, это имя и не нужно.
Для того чтобы сохранить промежуточный файл, скопировав его в другой файл, используется команда tee, помещаемая в то место конвейера, где нахо- дится промежуточный файл. Если сравнить конвейер с водопроводной трубой, то эта команда играет роль «тройника» (рис. 2.10). Переделаем предыдущий пример так, чтобы, по-прежнему сохраняя результаты поиска в файлеfile, обеспечить их вывод на экран:
$ find dir1 -name a1 | tee file | cat.
Рис. 2.10 Наглядное изображение команды tee
Если первой и последней командам конвейера не нужны соответственно клавиатура и экран (например, благодаря перенаправлению ввода-вывода), то все программы конвейера могут быть запущены в фоновом режиме записью символа «&» в конце конвейера.
Подобно тому, как команда запуска программы имеет код завершения, подобный код имеет и конвейер. При этом код завершения конвейера определя- ется кодом завершения программы, записанной в конвейере последней.
Командные списки. Такой список образуют конвейеры, разделенные сим- волами: «;», «&», «&&», «||». При этом в качестве конвейеров могут выступать и отдельные исполняемые файлы. Рассмотрим назначение перечисленных сим- волов:
; – элементы списка, соединяемые этим символом, запускаются по- следовательно. То есть программа (конвейер) справа от символа «;»
64 начинает выполняться только после завершения программы (конвейе- ра) слева. При этом программа слева выполняется в оперативном ре- жиме и поэтому может использовать экран и клавиатуру;
& – элементы списка, соединяемые этим символом, запускаются асин- хронно. При этом программа или конвейер слева от этого символа за- пускается в фоновом режиме;
&& – элементы списка, соединяемые этим символом, запускаются по- следовательно. При этом конвейер справа будет запущен только в том случае, если конвейер слева завершился успешно – с нулевым кодом завершения;
|| – в отличие от предыдущего случая для запуска конвейера справа требуется неудачное завершение конвейера слева (завершение с нену- левым кодом завершения).
Примеры командных списков:
1) $ mkdir dir1; cd dir1; pwd
/home/vlad/dir1 2) $ cp -r dir2 dir3 & cat > file1 3) $ mkdir dir1 && cd dir1 4) $
mkdir dir1 || echo "Ошибка создания каталога dir1"
Многоуровневая команда. Такая команда представляет собой текст одной команды, в которую должны быть подставлены результаты выполнения другой команды или команд. При этом результат вкладываемой команды представляет собой одну или несколько текстовых строк, отображаемых в стандартный вы- вод. Примеры таких команд: pwd, wc, ls, find. Каждая вкладываемая команда должна быть выделена одним из двух способов: а) заключена в обратные апо- строфы «`»; б) заключена в круглые скобки, которым предшествует символ
«$». Первый из этих способов применяется, в основном, для двухуровневых команд, а второй – для любого числа уровней вложенности.
Shell обрабатывает многоуровневую команду (как и любую другую) слева направо. При этом, встретив очередную вложенную команду, shell обеспечивает ее выполнение, а затем подставляет текст, полученный в резуль- тате этого выполнения, в командную строку. Если данный текст состоит из не- скольких строк, то shell заменяет каждую пару символов «возврат каретки» и
65
«перевод строки», разделяющих соседние строки, на символ пробела. В резуль- тате этого вставляемый текст представляет собой одну большую строку.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
Следующая двухуровневая команда выполняет уничтожение всех файлов и каталогов, простые имена которых начинаются с буквы d и которые располо- жены в поддереве файловой структуры, принадлежащем данному пользователю:
$ rm -r ‘find / -name ‘d*’’
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Обратите внимание, что при задании в команде find имени файла (или каталога) с помощью метасимволов, это имя обязательно должно быть заклю- чено в кавычки (одиночные или двойные). Это объясняется тем, что shell имеет свои метасимволы, одноименные метасимволам утилиты find. Кавычки играют роль «экранирующих» символов, сообщая shell о том, что все симво- лы, заключенные между ними, являются обычными символами, которые долж- ны быть переданы без изменений в запускаемую программу (в данном случае в программу find).
Полезно сравнить действие записанной двухуровневой команды с коман- дой: $ rm -r /d*. Последняя команда выполнит уничтожение не всех фай- лов и каталогов с заданным именем в поддереве пользователя, а лишь тех, для которых родительским каталогом является корень этого поддерева.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
Следующая команда имеет 4-уровневую структуру:
$ echo 111$(echo 222$(echo 333$(echo 444)))
111222333444
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
2.5.4 Переменные и выражения
Как и любой язык программирования, входной язык ИК позволяет зада- вать переменные. При этом под переменной понимается небольшая область ОП, содержащая данное, которое может быть использовано при выполнении команд shell
. В отличие от других языков программирования переменные shell не
66 нуждаются в объявлении типа, так как все они содержат данные одного типа – символьные строки.
Имя переменной может включать символы: латинские буквы, цифры,
«_». При этом имя не может начинаться с цифры. Как и всегда, для задания значения переменной используется оператор присваивания. В shell это сим- вол «=». Имя присваиваемой переменной помещается слева от этого символа, а справа – новое значение переменной. Для задания этого значения могут быть использованы следующие способы.
Непосредственное задание строки символов. Если эта строка состоит из одного слова, то ее можно не выделять. Для задания строки из нескольких слов обязательны двойные кавычки.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1=/home/vlad/a.txt
$ var2="/home/vlad/a.txt"
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В результате выполнения этих операторов переменныеvar1 иvar2 имеют одинаковое значение.
Задание значения другой переменной. Для этого перед именем перемен- ной в правой части оператора присваивания должен быть помещен символ «$».
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1=/home/vlad/a.txt
$ var2=$var1
$ echo $var2
/home/vlad/a.txt
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В этом примере значение переменнойvar1 используется для задания значения переменной var2. А значениеvar2 используется в качестве пара- метра командыecho.
Использование выходных данных команды shell. Оно выполняется точ- но так же, как и в многоуровневой команде (см. пп. 2.5.3). При этом имя любой программы, которая выдает свой результат в виде одной или нескольких строк символов, может быть записано справа от оператора присваивания, заключен-
67 ным в обратные апострофы «`», или может быть заключено в круглые скобки, которым предшествует символ «$».Shell сначала запускает указанную про- грамму на выполнение, а затем подставляет ее выходные данные в качестве значения заданной переменной.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var=`pwd`
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В данном примере shell сначала запустит на выполнение утилитуpwd, которая выдаст имя текущего каталога, затем подставит это имя в качестве зна- чения переменной var.
Использование команды ввода read. Оно позволяет ввести значения пе- ременных со стандартного ввода (с клавиатуры), не используя оператор при- сваивания. Для этого имена определяемых переменных должны быть перечис- лены в качестве параметров этой команды. Вводимые далее с клавиатуры (до нажатия ) слова распределяются между переменными так, что в одну переменную записывается одно слово. Если число переменных меньше числа слов в введенной строке, то все оставшиеся слова записываются в последнюю переменную. Если, наоборот, число переменных больше, то последние пере- менные получат пустое значение. Если с клавиатуры вместо обычных символов будет введен символ конца файла (>&<D>), то данная команда завершит- ся с ненулевым кодом завершения.
Команду read удобно использовать для того, чтобы присваивать пере- менным значения слов из некоторого текстового файла. Для этого достаточно перенаправить стандартный ввод с клавиатуры на ввод из требуемого файла.
Например, следующая команда присваивает переменным x, y, z значения слов из первой строки файла file:
$ read x y z < file
Таким образом, для того, чтобы определить обыкновенную переменную, достаточно хотя бы раз записать ее имя слева от оператора присваивания или записать его в качестве параметра команды read. После этого до конца вашей работы с данным shell значение данной переменной может использоваться в любом месте любой команды. Для этого имени переменной должен предше- ствовать символ «$», смысл которого в данном случае есть «значение перемен-
68 ной». Выше приведены примеры использования значения переменной в правой части оператора присваивания, а также в качестве параметра команды echo.
Если имя переменной следует отделить от символов, записанных сразу за ним, то это имя следует заключить в символы «{» и «}».
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var=abc
$ echo $varxy
$ echo ${var}xy abcxy
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В данном примере в качестве параметра первого оператора echoзаписа- но значение неопределенной ранее переменной varxy. В подобных случаях shell подставляет вместо неопределенной переменной пустое место. Второй операторecho получает в качестве своего параметра значение переменной var
(символы abc), к которому «подсоединены» символы xy.
Используя утилиту set (без параметров), можно вывести на экран пере- чень переменных, определенных в данном сеансе работы с shell, а также их значения. В состав данных переменных входят не только обыкновенные пере- менные, заданные операторами присваивания, но и переменные окружения – переменные, которые shell «наследует» от программы, запустившей его.
(В гл. 3 будет показано, что любая обрабатывающая программа имеет «роди- тельскую программу».) Рассмотрим некоторые переменные окружения:
1) HOME – содержит полное имя корневого каталога пользователя;
2) PATH – содержит перечень абсолютных имен каталогов, в которых shell выполняет поиск исполняемого файла в том случае, если для его задания в своей команде пользователь использовал простое имя файла. Имена-пути каталогов, записанные в данной переменной, раз- деляются символом «:». Следует отметить, что shell не производит поиск исполняемого файла в текущем каталоге по умолчанию, и для этого требуется явное задание текущего каталога в переменной PATH
(для этого используются символы «./»). Кроме того, заметим, что shell не использует данную переменную для поиска неисполняе- мых, например текстовых, файлов. Поэтому для задания таких файлов
69 в команде пользователя требуется или использовать их абсолютные имена, или обеспечить перед выполнением такой команды переход в родительский каталог файла;
3) PS1 – приглашение shell в командной строке (обычно – $);
4) PS2 – вторичное приглашение shell в командной строке (обычно –
>
). Выводится на экран в том случае, когда вводимая команда пользо- вателя занимает более одной строки.
Используя оператор присваивания, можно заменить содержимое пере- менной окружения подобно тому, как это делается для обыкновенных перемен- ных. Например, следующая команда добавляет в переменную PATHимя теку- щего каталога: $ PATH=${PATH}":./".
Изменение переменной окружения приведет к тому, что не только теку- щая программа shell, но и все запущенные ею программы будут использовать новое значение данной переменной. В то же время программы, являющиеся
«предками» данного shell, по-прежнему будут работать с ее прежним значе- нием.
Обыкновенные переменные можно добавить к переменным окружения, сделав их «наследуемыми». Для этого достаточно перечислить имена этих пе- ременных в качестве параметров команды export.
Подобно другим языкам программирования, входной язык shellпозво- ляет записывать выражения.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Выражение – совокупность нескольких переменных и (или)
констант, соединенных знаками операций. Различают арифмети-
ческие и логические выражения.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Арифметические выражения имеют при программировании для shell весьма ограниченное значение. Вспомним, что данный язык даже не имеет арифметических типов данных. Если все-таки требуется выполнить над пере- менными shell арифметические действия, то для этого следует использовать команду (функцию shell) expr.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ expr 5 + 3 8
70
$ expr 5 "*" 3 15
$ x=10
$ expr $x + 1 11
$ x=20
$ x=`expr $x + 2`
$ echo $x
22
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Заключение в кавычки знака умножения обусловлено тем, что данный символ является для shell метасимволом, и поэтому для устранения его спе- циальных свойств он должен быть «экранирован». Обратите внимание, что зна- ки арифметических операций должны быть окружены пробелами.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Логическое выражение – выражение, имеющее только два
значения – 0 (истина) и 1 (ложь).
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Операндами логического выражения являются операции отношения, каждая из которых или проверяет отношение файла (или строки символов) к заданному свойству, или сравнивает между собой два заданных числа (или две строки символов). Если проверяемое отношение выполняется, то результа- том операции отношения является 0, иначе – 1. Перечислим некоторые из опе- раций отношения:
-s file размер файла file больше 0
-r file для файла file разрешен доступ на чтение
-w file для файла file разрешен доступ на запись
-x file для файла file разрешено выполнение
-f file файл file существует и является обычным файлом
-d file файл file существует и является каталогом
-z string строка string имеет нулевую длину
-n string строка string имеет ненулевую длину string1 = string2 две строки идентичны string1 != две строки различны
71 string2 i1 -eq i2 число i1 равно числу i2 i1 -ne i2 число i1 не равно числу i2 i1 -lt i2 число i1 строго меньше числа i2 i1 -lе i2 число i1 меньше или равно числу i2
i1 -gt i2 число i1 строго больше числа i2
i1 -gе i2 число i1 больше или равно числу i2
При записи логического выражения отдельные операции отношения мо- гут соединяться друг с другом с помощью логических операций:
! – логическое отрицание;
-a – логическое И;
-o – логическое ИЛИ.
При этом наибольший приоритет имеет операция !, а наименьший –
-o
. Приоритеты операций определяют порядок их выполнения. Порядок вы- полнения логических операций можно изменить, используя круглые скобки.
Для shell характерно то, что запись логического выражения еще не означает его автоматического вычисления. Для этого требуется, чтобы элемен- ты логического выражения были записаны в качестве параметров команды test
. Результатом выполнения этой команды является код завершения: 0 – ло- гическое выражение истинно, 1 – ложно. Команду testможно задать одним из двух способов: 1) обычным способом; 2) заключив логическое выражение в квадратные скобки.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1 = 10; var2 = 20; var3 = 30 1) $ test $var1 –gt $var2 && echo "var1 > var2"
2) $ [ $var1 –gt $var2 ] || echo "var1 <= var2" var1 <= var2 3) $ test $var1 = $var2 && echo "var1 = var2"
4) $ [ $var1 = $var2 –o $var2 != $var3 ] && echo
"===="
====
5) $ test \($var1 –eq $var2 \) && echo "var1 = var2"
6) $ [ ! \($var1 –eq 0 \) ] && echo "var1 не равно 0"
72 var1 не равно 0 7) $ test \($ var1 != $var2 \) –a \($var1 –eq $var2
\) || echo "????"
????
8) $ [ abc ] && echo true true
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В примерах 1 и 2 операции отношения сравнивают численные значения переменных. В зависимости от этих значений выводятся соответствующие со- общения на экран. В примере 2 команда test задается с помощью квадратных скобок, которые обязательно отделяются от логического выражения пробелами.
В примерах 3 и 4 содержимое каждой переменной рассматривается не как число, а как строка символов. Обратите внимание, что операция проверки идентичности строк (=) в отличие от операции присваивания выделяется с обе- их сторон пробелами.
В примерах 5, 6 и 7 для выделения логического выражения или его частей используются круглые скобки. При записи каждой круглой скобки должны быть выполнены два требования: 1) непосредственно перед скобкой должен быть помещен символ «\»; 2) перед символом «\» и после скобки обязательно должны быть записаны пробелы. Наличие первого требования обусловлено тем, что круглые скобки рассматриваются интерпретатором shellкак слу- жебные символы. Для того, чтобы эти скобки не выполняли свои служебные функции, а были переданы без изменений в подпрограмму, выполняющую ко- манду test, они должны быть «экранированы». Такое «экранирование» и вы- полняет символ «\». Интересно отметить, что в примере 7 операции отношения
(записаны в круглых скобках) всегда дают противоположный результат. При этом в первой из них переменные сравниваются как строки символов, а во вто- рой рассматриваются их численные значения.
Пример 8 иллюстрирует тот факт, что команда testвыдает значение 0
(истина), если вместо логического выражения записано любое непустое слово.
Во всех приведенных выше примерах команда test, выполняющая вы- числение логического выражения, записывается в качестве первой команды командного списка, управляя выполнением второй команды этого списка. Дру- гим применением этой команды являются управляющие операторы shell.
73
1 2 3 4 5 6 7 8 9 10 ... 23
В отличие от простой команды составная команда позволяет пользовате- лю запустить не один, а несколько исполняемых файлов. Такая команда пред- ставляет собой или конвейер, или командный список, или многоуровневую ко- манду.
Конвейер программ. Имена исполняемых файлов, образующих конвейер, разделяются символом «|». Стандартный вывод программы, стоящей слева от этого символа, одновременно является стандартным вводом для программы, записанной справа. Пример конвейера:
$ find dir1 -name a1 | cat > file.
В этом примере утилитаfind выводит список файлов с простым именем a1
, находящихся в поддереве файловой структуры с корнемdir1(это подка- талог текущего каталога). Причем вывод осуществляется не на экран, а в файл на диске, из которого утилитаcat переписывает имена файлов в файлfile.
Программы, образующие конвейер, не конкурируют между собой из-за экрана и клавиатуры, так как клавиатура может быть нужна только первой, а экран – только последней программе конвейера. Поэтому эти программы за- пускаются shellодновременно (асинхронно). После запуска программы, рас- положенные по соседству в конвейере, взаимодействуют между собой через
63 промежуточный файл следующим образом. Программа, для которой этот файл является выходным, помещает в него свои данные построчно (в приведенном примере каждая строка содержит имя файла). Другая программа считывает эти данные также построчно, не дожидаясь завершения работы первой программы.
Заметим, что несмотря на то, что промежуточный файл реально существует на диске, его имя неизвестно для пользователя, которому, впрочем, это имя и не нужно.
Для того чтобы сохранить промежуточный файл, скопировав его в другой файл, используется команда tee, помещаемая в то место конвейера, где нахо- дится промежуточный файл. Если сравнить конвейер с водопроводной трубой, то эта команда играет роль «тройника» (рис. 2.10). Переделаем предыдущий пример так, чтобы, по-прежнему сохраняя результаты поиска в файлеfile, обеспечить их вывод на экран:
$ find dir1 -name a1 | tee file | cat.
Рис. 2.10 Наглядное изображение команды tee
Если первой и последней командам конвейера не нужны соответственно клавиатура и экран (например, благодаря перенаправлению ввода-вывода), то все программы конвейера могут быть запущены в фоновом режиме записью символа «&» в конце конвейера.
Подобно тому, как команда запуска программы имеет код завершения, подобный код имеет и конвейер. При этом код завершения конвейера определя- ется кодом завершения программы, записанной в конвейере последней.
Командные списки. Такой список образуют конвейеры, разделенные сим- волами: «;», «&», «&&», «||». При этом в качестве конвейеров могут выступать и отдельные исполняемые файлы. Рассмотрим назначение перечисленных сим- волов:
; – элементы списка, соединяемые этим символом, запускаются по- следовательно. То есть программа (конвейер) справа от символа «;»
64 начинает выполняться только после завершения программы (конвейе- ра) слева. При этом программа слева выполняется в оперативном ре- жиме и поэтому может использовать экран и клавиатуру;
& – элементы списка, соединяемые этим символом, запускаются асин- хронно. При этом программа или конвейер слева от этого символа за- пускается в фоновом режиме;
&& – элементы списка, соединяемые этим символом, запускаются по- следовательно. При этом конвейер справа будет запущен только в том случае, если конвейер слева завершился успешно – с нулевым кодом завершения;
|| – в отличие от предыдущего случая для запуска конвейера справа требуется неудачное завершение конвейера слева (завершение с нену- левым кодом завершения).
Примеры командных списков:
1) $ mkdir dir1; cd dir1; pwd
/home/vlad/dir1 2) $ cp -r dir2 dir3 & cat > file1 3) $ mkdir dir1 && cd dir1 4) $
mkdir dir1 || echo "Ошибка создания каталога dir1"
Многоуровневая команда. Такая команда представляет собой текст одной команды, в которую должны быть подставлены результаты выполнения другой команды или команд. При этом результат вкладываемой команды представляет собой одну или несколько текстовых строк, отображаемых в стандартный вы- вод. Примеры таких команд: pwd, wc, ls, find. Каждая вкладываемая команда должна быть выделена одним из двух способов: а) заключена в обратные апо- строфы «`»; б) заключена в круглые скобки, которым предшествует символ
«$». Первый из этих способов применяется, в основном, для двухуровневых команд, а второй – для любого числа уровней вложенности.
Shell обрабатывает многоуровневую команду (как и любую другую) слева направо. При этом, встретив очередную вложенную команду, shell обеспечивает ее выполнение, а затем подставляет текст, полученный в резуль- тате этого выполнения, в командную строку. Если данный текст состоит из не- скольких строк, то shell заменяет каждую пару символов «возврат каретки» и
65
«перевод строки», разделяющих соседние строки, на символ пробела. В резуль- тате этого вставляемый текст представляет собой одну большую строку.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
Следующая двухуровневая команда выполняет уничтожение всех файлов и каталогов, простые имена которых начинаются с буквы d и которые располо- жены в поддереве файловой структуры, принадлежащем данному пользователю:
$ rm -r ‘find / -name ‘d*’’
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Обратите внимание, что при задании в команде find имени файла (или каталога) с помощью метасимволов, это имя обязательно должно быть заклю- чено в кавычки (одиночные или двойные). Это объясняется тем, что shell имеет свои метасимволы, одноименные метасимволам утилиты find. Кавычки играют роль «экранирующих» символов, сообщая shell о том, что все симво- лы, заключенные между ними, являются обычными символами, которые долж- ны быть переданы без изменений в запускаемую программу (в данном случае в программу find).
Полезно сравнить действие записанной двухуровневой команды с коман- дой: $ rm -r /d*. Последняя команда выполнит уничтожение не всех фай- лов и каталогов с заданным именем в поддереве пользователя, а лишь тех, для которых родительским каталогом является корень этого поддерева.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
Следующая команда имеет 4-уровневую структуру:
$ echo 111$(echo 222$(echo 333$(echo 444)))
111222333444
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
2.5.4 Переменные и выражения
Как и любой язык программирования, входной язык ИК позволяет зада- вать переменные. При этом под переменной понимается небольшая область ОП, содержащая данное, которое может быть использовано при выполнении команд shell
. В отличие от других языков программирования переменные shell не
66 нуждаются в объявлении типа, так как все они содержат данные одного типа – символьные строки.
Имя переменной может включать символы: латинские буквы, цифры,
«_». При этом имя не может начинаться с цифры. Как и всегда, для задания значения переменной используется оператор присваивания. В shell это сим- вол «=». Имя присваиваемой переменной помещается слева от этого символа, а справа – новое значение переменной. Для задания этого значения могут быть использованы следующие способы.
Непосредственное задание строки символов. Если эта строка состоит из одного слова, то ее можно не выделять. Для задания строки из нескольких слов обязательны двойные кавычки.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1=/home/vlad/a.txt
$ var2="/home/vlad/a.txt"
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В результате выполнения этих операторов переменныеvar1 иvar2 имеют одинаковое значение.
Задание значения другой переменной. Для этого перед именем перемен- ной в правой части оператора присваивания должен быть помещен символ «$».
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1=/home/vlad/a.txt
$ var2=$var1
$ echo $var2
/home/vlad/a.txt
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В этом примере значение переменнойvar1 используется для задания значения переменной var2. А значениеvar2 используется в качестве пара- метра командыecho.
Использование выходных данных команды shell. Оно выполняется точ- но так же, как и в многоуровневой команде (см. пп. 2.5.3). При этом имя любой программы, которая выдает свой результат в виде одной или нескольких строк символов, может быть записано справа от оператора присваивания, заключен-
67 ным в обратные апострофы «`», или может быть заключено в круглые скобки, которым предшествует символ «$».Shell сначала запускает указанную про- грамму на выполнение, а затем подставляет ее выходные данные в качестве значения заданной переменной.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var=`pwd`
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В данном примере shell сначала запустит на выполнение утилитуpwd, которая выдаст имя текущего каталога, затем подставит это имя в качестве зна- чения переменной var.
Использование команды ввода read. Оно позволяет ввести значения пе- ременных со стандартного ввода (с клавиатуры), не используя оператор при- сваивания. Для этого имена определяемых переменных должны быть перечис- лены в качестве параметров этой команды. Вводимые далее с клавиатуры (до нажатия
Команду read удобно использовать для того, чтобы присваивать пере- менным значения слов из некоторого текстового файла. Для этого достаточно перенаправить стандартный ввод с клавиатуры на ввод из требуемого файла.
Например, следующая команда присваивает переменным x, y, z значения слов из первой строки файла file:
$ read x y z < file
Таким образом, для того, чтобы определить обыкновенную переменную, достаточно хотя бы раз записать ее имя слева от оператора присваивания или записать его в качестве параметра команды read. После этого до конца вашей работы с данным shell значение данной переменной может использоваться в любом месте любой команды. Для этого имени переменной должен предше- ствовать символ «$», смысл которого в данном случае есть «значение перемен-
68 ной». Выше приведены примеры использования значения переменной в правой части оператора присваивания, а также в качестве параметра команды echo.
Если имя переменной следует отделить от символов, записанных сразу за ним, то это имя следует заключить в символы «{» и «}».
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var=abc
$ echo $varxy
$ echo ${var}xy abcxy
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В данном примере в качестве параметра первого оператора echoзаписа- но значение неопределенной ранее переменной varxy. В подобных случаях shell подставляет вместо неопределенной переменной пустое место. Второй операторecho получает в качестве своего параметра значение переменной var
(символы abc), к которому «подсоединены» символы xy.
Используя утилиту set (без параметров), можно вывести на экран пере- чень переменных, определенных в данном сеансе работы с shell, а также их значения. В состав данных переменных входят не только обыкновенные пере- менные, заданные операторами присваивания, но и переменные окружения – переменные, которые shell «наследует» от программы, запустившей его.
(В гл. 3 будет показано, что любая обрабатывающая программа имеет «роди- тельскую программу».) Рассмотрим некоторые переменные окружения:
1) HOME – содержит полное имя корневого каталога пользователя;
2) PATH – содержит перечень абсолютных имен каталогов, в которых shell выполняет поиск исполняемого файла в том случае, если для его задания в своей команде пользователь использовал простое имя файла. Имена-пути каталогов, записанные в данной переменной, раз- деляются символом «:». Следует отметить, что shell не производит поиск исполняемого файла в текущем каталоге по умолчанию, и для этого требуется явное задание текущего каталога в переменной PATH
(для этого используются символы «./»). Кроме того, заметим, что shell не использует данную переменную для поиска неисполняе- мых, например текстовых, файлов. Поэтому для задания таких файлов
69 в команде пользователя требуется или использовать их абсолютные имена, или обеспечить перед выполнением такой команды переход в родительский каталог файла;
3) PS1 – приглашение shell в командной строке (обычно – $);
4) PS2 – вторичное приглашение shell в командной строке (обычно –
>
). Выводится на экран в том случае, когда вводимая команда пользо- вателя занимает более одной строки.
Используя оператор присваивания, можно заменить содержимое пере- менной окружения подобно тому, как это делается для обыкновенных перемен- ных. Например, следующая команда добавляет в переменную PATHимя теку- щего каталога: $ PATH=${PATH}":./".
Изменение переменной окружения приведет к тому, что не только теку- щая программа shell, но и все запущенные ею программы будут использовать новое значение данной переменной. В то же время программы, являющиеся
«предками» данного shell, по-прежнему будут работать с ее прежним значе- нием.
Обыкновенные переменные можно добавить к переменным окружения, сделав их «наследуемыми». Для этого достаточно перечислить имена этих пе- ременных в качестве параметров команды export.
Подобно другим языкам программирования, входной язык shellпозво- ляет записывать выражения.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Выражение – совокупность нескольких переменных и (или)
констант, соединенных знаками операций. Различают арифмети-
ческие и логические выражения.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Арифметические выражения имеют при программировании для shell весьма ограниченное значение. Вспомним, что данный язык даже не имеет арифметических типов данных. Если все-таки требуется выполнить над пере- менными shell арифметические действия, то для этого следует использовать команду (функцию shell) expr.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ expr 5 + 3 8
70
$ expr 5 "*" 3 15
$ x=10
$ expr $x + 1 11
$ x=20
$ x=`expr $x + 2`
$ echo $x
22
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Заключение в кавычки знака умножения обусловлено тем, что данный символ является для shell метасимволом, и поэтому для устранения его спе- циальных свойств он должен быть «экранирован». Обратите внимание, что зна- ки арифметических операций должны быть окружены пробелами.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Логическое выражение – выражение, имеющее только два
значения – 0 (истина) и 1 (ложь).
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Операндами логического выражения являются операции отношения, каждая из которых или проверяет отношение файла (или строки символов) к заданному свойству, или сравнивает между собой два заданных числа (или две строки символов). Если проверяемое отношение выполняется, то результа- том операции отношения является 0, иначе – 1. Перечислим некоторые из опе- раций отношения:
-s file размер файла file больше 0
-r file для файла file разрешен доступ на чтение
-w file для файла file разрешен доступ на запись
-x file для файла file разрешено выполнение
-f file файл file существует и является обычным файлом
-d file файл file существует и является каталогом
-z string строка string имеет нулевую длину
-n string строка string имеет ненулевую длину string1 = string2 две строки идентичны string1 != две строки различны
71 string2 i1 -eq i2 число i1 равно числу i2 i1 -ne i2 число i1 не равно числу i2 i1 -lt i2 число i1 строго меньше числа i2 i1 -lе i2 число i1 меньше или равно числу i2
i1 -gt i2 число i1 строго больше числа i2
i1 -gе i2 число i1 больше или равно числу i2
При записи логического выражения отдельные операции отношения мо- гут соединяться друг с другом с помощью логических операций:
! – логическое отрицание;
-a – логическое И;
-o – логическое ИЛИ.
При этом наибольший приоритет имеет операция !, а наименьший –
-o
. Приоритеты операций определяют порядок их выполнения. Порядок вы- полнения логических операций можно изменить, используя круглые скобки.
Для shell характерно то, что запись логического выражения еще не означает его автоматического вычисления. Для этого требуется, чтобы элемен- ты логического выражения были записаны в качестве параметров команды test
. Результатом выполнения этой команды является код завершения: 0 – ло- гическое выражение истинно, 1 – ложно. Команду testможно задать одним из двух способов: 1) обычным способом; 2) заключив логическое выражение в квадратные скобки.
· · · · · · · · · · · · · · · · · · · · · · · · ·
Пример
· · · · · · · · · · · · · · · · · · · · · · · · ·
$ var1 = 10; var2 = 20; var3 = 30 1) $ test $var1 –gt $var2 && echo "var1 > var2"
2) $ [ $var1 –gt $var2 ] || echo "var1 <= var2" var1 <= var2 3) $ test $var1 = $var2 && echo "var1 = var2"
4) $ [ $var1 = $var2 –o $var2 != $var3 ] && echo
"===="
====
5) $ test \($var1 –eq $var2 \) && echo "var1 = var2"
6) $ [ ! \($var1 –eq 0 \) ] && echo "var1 не равно 0"
72 var1 не равно 0 7) $ test \($ var1 != $var2 \) –a \($var1 –eq $var2
\) || echo "????"
????
8) $ [ abc ] && echo true true
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
В примерах 1 и 2 операции отношения сравнивают численные значения переменных. В зависимости от этих значений выводятся соответствующие со- общения на экран. В примере 2 команда test задается с помощью квадратных скобок, которые обязательно отделяются от логического выражения пробелами.
В примерах 3 и 4 содержимое каждой переменной рассматривается не как число, а как строка символов. Обратите внимание, что операция проверки идентичности строк (=) в отличие от операции присваивания выделяется с обе- их сторон пробелами.
В примерах 5, 6 и 7 для выделения логического выражения или его частей используются круглые скобки. При записи каждой круглой скобки должны быть выполнены два требования: 1) непосредственно перед скобкой должен быть помещен символ «\»; 2) перед символом «\» и после скобки обязательно должны быть записаны пробелы. Наличие первого требования обусловлено тем, что круглые скобки рассматриваются интерпретатором shellкак слу- жебные символы. Для того, чтобы эти скобки не выполняли свои служебные функции, а были переданы без изменений в подпрограмму, выполняющую ко- манду test, они должны быть «экранированы». Такое «экранирование» и вы- полняет символ «\». Интересно отметить, что в примере 7 операции отношения
(записаны в круглых скобках) всегда дают противоположный результат. При этом в первой из них переменные сравниваются как строки символов, а во вто- рой рассматриваются их численные значения.
Пример 8 иллюстрирует тот факт, что команда testвыдает значение 0
(истина), если вместо логического выражения записано любое непустое слово.
Во всех приведенных выше примерах команда test, выполняющая вы- числение логического выражения, записывается в качестве первой команды командного списка, управляя выполнением второй команды этого списка. Дру- гим применением этой команды являются управляющие операторы shell.
73
1 2 3 4 5 6 7 8 9 10 ... 23