А. Робачевский - Операционная система UNIX (1114671), страница 15
Текст из файла (страница 15)
Передаются как единоеслово, будучи заключенным в кавычки:$2 $3 . .$@Все параметры, переданные скрипту. Передаются как отдельныеслова, будучи заключенным в кавычки:. .Эти переменные редко используются при работе в командной строке, основ!ная область их применения — скрипты. Рассмотрим несколько примеров.Текст скриптаЗапуск скриптаа4echo$0echo $1 $2 $3echo $1 $2 $3а2 аЗ а4www.books-shop.comUNIXПеременные $1, $2, ... $9 содержат значения позиционных параметров —аргументов запущенного скрипта. В $1 находится первый аргументв$2 — а2 и т.
д. до девятого аргумента. При необходимости передать боль!шее число аргументов, требуется использовать команду shift n, производя!щую сдвиг значений аргументов на п позиций (по умолчанию — на однупозицию). Приведенный скрипт иллюстрирует этот прием. В переменной$0 находится имя запущенного скрипта. Здесь наблюдается полная ана!логия с массивом параметров argv[], передаваемом программе на языке С.Значение $# равно числу позиционных параметров. Его удобно использо!вать при проверке соответствия числа введенных пользователем парамет!ров требуемому.Текст скриптаif [ $#2 ]thenecho u s a g e : $0 argl arg2exit 1fiЗапуск скрипта$ test2.shusage: test2.sh$h2$arg2В данном примере использовано условное выражение if и проверка, кото!рые мы рассмотрим ниже.Код возврата последней выполненной задачи ($?) удобно использовать в ус!ловных выражениях.
По правилам успешным завершением задачи считаетсякод возврата, равный 0, ненулевой код возврата свидетельствует об ошибке.Код возврата скриптов генерируется с помощью команды exit п, где п — кодвозврата (см. предыдущий пример). В приведенном ниже примере определя!ется, зарегистрирован ли в системе пользователь с именемДляэтого программой grep(l) производится поиск слова sergey в файле паролей.В случае удачи grep(l) возвращает 0. Если слово не найдено, то grep(l) воз!вращает ненулевое значение, в данном случае это свидетельствует, что поль!зователь с именем sergey в системе не зарегистрирован.Текст скрипта test3.sh:grep sergey /etc/passwdif [ $? ne 0 ]thenecho пользователь sergey в системе не зарегистрированfiКаждый активный процесс в UNIX имеет уникальный идентификаторпроцесса, PID. Запуская скрипт, вы порождаете в системе процесс с уни!кальным PID.
Значение PID сохраняется в переменной $$. Эту перемен!ную удобно использовать в названиях временных файлов, поскольку ихимена будут уникальными, например:www.books-shop.com661. Работа всистеме UNIXТекст скрипта test4.sh:$Перенаправление ввода/выводаКаждая запущенная из командного интерпретатора программа получаеттри открытых потока ввода/вывода:Пстандартный вводстандартный выводстандартный вывод ошибокПо умолчанию все эти потоки ассоциированы с терминалом. То есть лю!бая программа, не использующая потоки, кроме стандартных, будет ожи!дать ввода с клавиатуры терминала, весь вывод этой программы, включаясообщения об ошибках, будет происходить на экран терминала.
Большоечисло утилит, с которыми вам предстоит работать, используют толькостандартные потоки. Для таких программ shell позволяет независимо пе!ренаправлять потоки ввода/вывода. Например, можно подавить вывод со!общений об ошибках, установить ввод или вывод из файла и даже пере!дать вывод одной программы на ввод другой.В табл. 1.9 приведен синтаксис перенаправления ввода/вывода, а на рис.
1.9схематически показаны примеры перенаправления потоков.Таблица 1.9. Перенаправление потоков>file<fileр1 |р2n>filen>&mПеренаправление стандартного потока вывода в файл fileДобавление в файл file данных из стандартного потока выводаПолучение стандартного потока ввода из файла fileПередача стандартного потока вывода программы р1 в поток ввода р2Переключение потока вывода из файла с дескриптором п в файл fileTo же, но записи добавляются в файл fileСлияние потоков с дескрипторами"Ввод здесь": используется стандартный поток ввода до подстроки str.При этом выполняются подстановки метасимволов командного интерпре%татораTo же, но подстановки не выполняютсяРассмотрим несколько примеров перенаправления потоков.Запуск некой программы ведения журнала можно выполнить следующимобразом:$ loggerwww.books-shop.com67среда UNIXПри этом вывод программы logger будет записываться в конец файласохраняя все предыдущие записи.
Если файла file.log не существу!ет, он будет создан. В отличие от этого, использование символа '>' указы!вает, что сначала следует очистить файл, а затем производить запись.Стандартным потокам ввода, вывода и вывода ошибок присваиваются де!скрипторы — числовые значения, являющиеся указателями на соответст!вующий поток. Они, соответственно, равны О, 1 и 2. Перенаправлять по!токи можно, используя эти числовые значения. Таким образом, предыду!щему примеру эквивалентна следующая запись:$ logger.
logРис. 1.9. Пример перенаправления стандартных потоковЧаще всего числовое значение дескриптора потока используется для пото!ка ошибок. Например, чтобы подавить вывод ошибок, можно использо!вать следующую запись:$ run 2>/dev/nullгдеявляется псевдоустройством, удаляющим все введенные внего символы.Командный интерпретатор предоставляет возможность слияния потоков.Например, при запуске команды$2>S1 &сообщения об ошибках будут также выводиться в файл /dev/null. Символ'&' перед именем потока необходим, чтобы отличить его от файла с име!нем 1. Заметим, что изменение порядка двух перенаправлений потоковприведет к тому, что сообщения об ошибках будут по!прежнему выводить!ся на экран.
Дело в том, что Shell анализирует командную строку слеванаправо, таким образом сначала будет осуществлено слияние потоков иwww.books-shop.comГлаваРабота всистеме UNIXоба будут указывать на терминал пользователя, а затем стандартный потоквыводабудет перенаправлен в файлПередача потока вывода одной программы в поток ввода другой осуществ!ляется с помощью конвейера(программного канала). Программные ка!налы часто используются для фильтрации вывода некоторой команды:$ ps — ef I grepпозволяет получить информацию о конкретном процессе myproc.
Утилитаps(l) выводит на экран информацию обо всех процессах в системе, про!грамма grep(l) фильтрует этот поток, оставляя лишь строки, в которыхприсутствует словоМожно усложнить задачу и попытаться получить идентификатор процессаmyproc. Однако здесь нам не обойтись без других средств системы. В дан!ном случае мы будем использовать интерпретатор$ ps ef | grep myproc I awkprint $2Идея заключается в фильтрации второго поля записи о процессе myproc,содержащего идентификатор процесса (см. описание утилитыИногда возникает необходимость разместить поток ввода вместе с коман!дой.
Для этого используется выражение "ввод здесь". Проиллюстрируемего на примере:$ at Dec 31cat| elmНовым Годом"По определению, команда at(l) устанавливает вызов команды, полученнойею со стандартного ввода (клавиатуры терминала), на определенное время(в данном случае — на 31 декабря каждого года). С помощью выражения"ввод здесь" мы явно задали вид этой команды, точнее комплекса команд:cat(l) передает текст поздравления программеотвечающей за от!правление сообщения электронной почты.Команды, функции и программыВсе команды, которые вводятся в строке приглашения shell, относятся кодной из следующих категорий:Более правильно было бы записать:$ ps !ef I grep myproc | grep !v grepДело в том, что в списке, созданном командойбудут две строки, содержащие словоmyproc: собственно строка процесса myproc и строка процесса grep(l) с параметромmyproc (psимяпородившей процесс, вместе со всеми пара!метрами).www.books-shop.comПользовательскаяUNIXвстроенные функциифункции shell, определенные пользователемвнешние программы и утилитыНепосредственное отношение к shell имеют только первые две категории,а программы и утилиты являются обычными исполняемыми файлами.Запуск встроенной функции не требует порождения нового процесса, по!скольку эта функция реализована в самой программе shell (например,Соответственно, встроенные функции shell выполняются быстреевсего.
Рассмотрим важнейшие встроенные функции shell.:Пустая команда. Код возврата всегда 0 (успех).Пустая команда удобна для создания бесконечныхциклов, например:while :dodoneТекущий командный интерпретатор выполняет команды,указанные в файлеПри этом не происходит поро%ждения нового shell, как в случае запуска на выполнениеrunme. Например, использование в скрипте команды.выполнит команды фай%ла include_script, как если бы они являлись частью теку%щего скрипта..
runmebreak [л]Производит выход из цикла for или while. Если пара[метр л указан, происходит выход из вложенных цикловps %ef I awkprint $1Iwhile read uid piddoif [$pid !eq $PID]thenecho pid=$pid user=$uidbreakfidonecdecho [string]execОсуществляет переход в каталогЕсли параметр неуказан, происходит переход в домашний каталогСтрока string выводится на стандартное устройство вы%вода (терминал)Выполняет программу runme, заменяя ею текущий ко%мандный интерпретатор. Например, если в login shell(командном интерпретаторе, запускаемом при регистра%ции пользователя в системе) мы вызовем exec Is, то послевывода имен файлов текущего каталога произойдет за%вершение работы в системеȾɚɧɧɚɹɜɟɪɫɢɹɤɧɢɝɢɜɵɩɭɳɟɧɚɷɥɟɤɬɪɨɧɧɵɦɢɡɞɚɬɟɥɶɫɬɜɨɦ%RRNVVKRSɊɚɫɩɪɨɫɬɪɚɧɟɧɢɟɩɪɨɞɚɠɚɩɟɪɟɡɚɩɢɫɶɞɚɧɧɨɣɤɧɢɝɢɢɥɢɟɟɱɚɫɬɟɣɁȺɉɊȿɓȿɇɕɈɜɫɟɯɧɚɪɭɲɟɧɢɹɯɩɪɨɫɶɛɚɫɨɨɛɳɚɬɶɩɨɚɞɪɟɫɭpiracy@books-shop.comj obswww.books-shop.comПользовательскаяUNIX71trap commandsig2Определяет команду command, которая будет выполненапри получении сигналов, указанных в качестве аргументовsig.
См. раздел "Сигналы" ранее в этой главеtype nameПоказывает, как name будет интерпретироваться команд%ным интерпретаторомВыводит или устанавливает значение пределов, ограничи%вающих использование задачей системных ресурсов(времени процессора, памяти, дискового пространства).рассматриваться в главе 2Устанавливает маску прав доступа для вновь создаваемыхфайлов равной пппunsetw a i t padvar2 .Удаляет переменные, указанные в качестве аргументов, изсписка определенных переменных командного интерпре%татора. Некоторые переменные, например PATH, PS1,PS2, не могут быть удаленыОжидает завершения выполнения процесса с идентифи%катороми возвращает его код возвратаПользователь может определить функцию командного интерпретатора ииспользовать ее как встроенную функцию shell.
С другой стороны, функ!ции мало отличаются от скриптов, включая синтаксис и передачу аргумен!тов. Однако являясь частью shell, функции работают быстрее.Синтаксис функции имеет следующий вид:{}Как можно заметить, телом функции является обычный скрипт shell.В качестве примера приведем функциюприглашении shell имя текущего каталога.позволяющую отобразить вmcd{cd}Подстановки, выполняемые командным интерпретаторомПрежде чем выполнить команду, указанную либо в командной строке, ли!бо в скрипте, командный интерпретатор производит определенную после!довательность действий:1.
Анализирует синтаксис команды. В случае, если обнаружена синтак!сическая ошибка, выводится соответствующее сообщение. Естествен!www.books-shop.com72ГлаваРабота всистеме UNIXно, shell анализирует командную строку в соответствии с синтаксисомсобственного языка, а не семантику вызова конкретной команды, на!пример, наличие тех или иных аргументов.2. Производит подстановки, а именно:• Заменяетвсеуказанныепеременныеихзначениями.Например, если значение переменной var равното привызове команды f i n d $var !name sh !print переменнаябудет заменена ее значением. Другими словами, фактиче!ский запуск команды будет иметь вид:f i n d / u s r / b i n !name sh !print•Формирует списки файлов, заменяя шаблоны.