355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Дэвид Тейнсли » Linux и UNIX: программирование в shell. Руководство разработчика » Текст книги (страница 4)
Linux и UNIX: программирование в shell. Руководство разработчика
  • Текст добавлен: 15 октября 2016, 00:39

Текст книги "Linux и UNIX: программирование в shell. Руководство разработчика"


Автор книги: Дэвид Тейнсли



сообщить о нарушении

Текущая страница: 4 (всего у книги 25 страниц)

cat /home/acccmnts/qtr_04 99 | /apps/bm/trials.awk | sort | lp

Поместим ее в файл:

$ cat > quarterend

cat /home/accounts/qtr_0499 | /apps/bin/trials.awk | sort | lp

Сделаем файл исполняемым:

$ chmod 744 quarterend

Теперь запустим этот файл в фоновом режиме посредством команды nohup, направив результаты работы сценария в файл qtr.out.

$ nohup ./quarterend > qtr.out 2>&l &

[5] 182

Обратите внимание на то, что при вызове файла quarterend указано путевое имя '. /.' Тем самым интерпретатору shell дается указание искать данную команду в текущем каталоге.

3.5. Заключение

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

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

ГЛАВА 4

Подстановка имен файлов

При работе в режиме командной строки довольно много времени уходит на поиск необходимых файлов. Интерпретатор shell предлагает набор метасимволов, позволяющих находить файлы, имена которых соответствуют предложенному шаблону.

Вот список основных метасимволов:

* Соответствует произвольной строке, содержащей ноль и более символов

? Соответствует любому символу

[…] Соответствует любому символу из числа заключенных в скобки

[!…] Соответствует любому символу за исключением тех, которые указаны в скобках

Когда интерпретатор shell встречает указанные символы в командной строке, он обрабатывает их особым образом, если только вы не защитили их с помощью кавычек, о чем говорится в главе 15.

4.1. Применение метасимвола '*'

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

$ ls app*

appdva app_tapes

appdva_SLA

Вот как можно получить список файлов, имеющих расширение doc:

$ ls *.doc

accounts.doc qtr_end.doc

Представленная ниже команда находит файлы, у которых имя начинается со строки "cl", а расширение равно sed:

$ ls cl*.sed

cleanlogs.sed cleanmeup.sed

cleanmessages.sed

Звездочку удобно применять, когда, например, не хочется вводить полное имя каталога при переходе в него:

$ cd /etc

$ ls -l | grep ^d

drwxr‑xr‑x 2 root root 1024 Jan 26 14:41 cron.daily

drwxr‑xr‑x 2 root root 1024 Jan 27 1998 cron.hourly

drwxr‑xr‑x 2 root root 1024 Jan 27 1998 cron.monthly

drwxr‑xr‑x 2 root root 1024 Jan 26 14:37 cron.weekly

$ cd cron.w* S pwd

/etc/cron.weekly

4.2. Применение метасимвола '?'

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

$ ls ??R*

BAREAD

Следующая команда ищет файлы с именами, начинающимися со строки "conf", за которой следуют два произвольных символа и расширение log:

$ ls conf??.log .

confl2.log conf.2.log

conf25.log

Вот как можно найти файлы, имена которых состоят не менее чем из четырех символов, причем первым является символ 'f', а последним – 's':

$ ls f??*s

ftpaccess ftphosts ftpconversions ftpusers ftpgroups

4.3. Применение метасимволов […] и [!…]

Метасимволы [… ] соответствуют любому символу из числа тех, что указаны в квадратных скобках. Представленная ниже команда выводит список файлов, имена которых начинаются с символа 'i' или 'o':

$ ls [io]*

inetd.conf ioctl.save outputrc

info‑dir inputrc

initrunlvl issue

inittab issue.net

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

$ ls log.[0-9]*

log.0323 log.0325 log.0324 log.0326

Метасимволы [!…] соответствуют любому символу из числа тех, что не указаны

в квадратных скобках. Если в предыдущем примере на первом месте в скобках поставить восклицательный знак, команда будет искать файлы с именами log, в расширении которых первый символ не является цифрой: '

$ ls log.[!0-9]*

log.sybase

Приведенная ниже команда ищет файлы, имена которых начинаются со строки "LPS", два следующих символа могут быть произвольными, затем идет символ, не являющийся цифрой, а за ним – произвольная строка:

$ ls LPS??[!0-9]*

LPSILP LPSOSI LPSOPS LPSPOPQTR

Поиск файлов, имена которых начинаются с символа верхнего регистра, производится посредством такой команды:

$ ls [A‑Z]*

Следующая команда ищет файлы, имена которых, наоборот, начинаются с символа нижнего регистра:

$ 1а [а–z]*

А эта команда находит файлы, в начале имени которых стоит цифра:

$ ls [0-9]*

Вот как можно найти все скрытые файлы (такие как .profile, .rhosts, .history и т. д.):

$ ls .*

4.4. Заключение

Метасимволы представляют собой универсальный инструмент поиска строк по шаблону. С их помощью легко находить нужные файлы и каталоги. Далее мы более подробно рассмотрим способы применения метасимволов в составе регулярных выражений.

ГЛАВА 5

Ввод и вывод данных в интерпретаторе shell

Команды и сценарии могут получать входные данные двумя способами: из стандартного входного потока (связан с клавиатурой) или из файла. Аналогичное разделение существует и при выводе данных: результаты работы команды или сценария по умолчанию направляются на экран терминала, но можно перенаправить их в файл. Если в процессе работы возникают ошибки, сообщения о них тоже отображаются на экране. Чтобы избежать этого, нужно перенаправить поток ошибок в файл.

В этой главе рассматриваются следующие темы:

   • работа со стандартными потоками ввода, вывода и ошибок;

   • переадресация ввода и вывода.

5.1. Команда echo

Команда echo отображает на экране указанную строку текста. Общий ее формат таков:

echo строка

В строке могут встречаться различные управляющие символы, ниже перечислены основные из них: c запрет отображения концевого символа новой строки f прогон страницы n новая строка t горизонтальная табуляция

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

$ echo "Как вас зовут?tc"

Как вас зовут? $

Здесь $ -cимвол приглашения.

По умолчанию подразумевается, что в конце строки находится символ новой строки:

$ echo "Как вас зовут?"

Как вас зовут? $

В строке можно вычислять значения переменных интерпретатора shell и даже других команд. Например, следующая команда сообщает о том, каков начальный каталог текущего пользователя (переменная среды $номе) и к какому терминалу он подключен (команда tty заключена в обратные кавычки, чтобы интерпретатор shell поместил в строку результат ее выполнения):

$ echo "Ваш начальный каталог $HOME, вы подключены к терминалу `tty`"

Ваш начальный каталог /home/dave, вы подключены к терминалу /dev/ttyp1

В Linux…

Чтобы запретить вывод символа новой строки, укажите опцию -n:

$ echo -n "Как вас зовут?"

Управляющие символы по умолчанию не распознаются. Чтобы активизировать их, задайте опцию -e:

$ echo -e "Как вас зовут?tc"

Как вас зовут? $

Для вывода дополнительных пустых строк используйте управляющий символ n:

$ echo "Выводим 3 пустые строхиnnnОК"

Выводим 3 пустые строки

OK

В любом месте строки можно размещать символы табуляции:

$ echo "Один символ табуляцииtДве табуляцииttOK"

Один символ табуляции Два символа табуляции ОК

Чтобы перенаправить результаты работы команды echo в файл, воспользуйтесь оператором '>':

$ echo "Строка занесена в файл." > myfile

В этом случае содержимое файла myfile будет заменено. Существует также оператор '>>', который позволяет добавить строку в конец файла:

$ echo "Отчет создал пользователь $LOGNAME. `date` " >> myfile

Здесь используется переменная среды $LOGNAME, которая содержит регистрационное имя текущего пользователя.

Рассмотрим содержимое файла myfile:

$ cat myfile

Строка занесена в файл.

Отчет создал пользователь root. Sat May 22 18:25:06 GMT 1999

Одной из проблем, с которыми часто сталкиваются начинающие пользователи при работе с командой echo, является включение в строку двойных кавычек. Символы двойных кавычек имеют специальное назначение в интерпретаторе shell,

поэтому должны быть защищены с помощью обратной косой черты. Вот как выводится на экран строка "/dev/rmt0":

$ echo ""/dev/rmt0""

"/dev/rmt0"

5.2. Команда read

Команда read читает одну строку из стандартного входного потока и записывает ее содержимое в указанные переменные. Если задана единственная переменная, в нее записывается вся строка. В результате ввода команды read без параметров строка помешается в переменную среды $reply. При указании нескольких переменных в первую из них записывается первое слово строки, во вторую – второе слово и т. д. Последней переменной присваивается остаток строки.

Общий формат команды таков:

read переменная1 переменная2…

В следующем примере в переменную name записывается весь вводимый с клавиатуры текст до тех пор, пока не будет нажата клавиша [Enter]:

$ read name Джон Алан Доу $ echo $name

Джон Алан Доу

Представленная ниже команда заносит введенные имя и фамилию в две переменные. В качестве разделителя между словами используется пробел.

$ read name surname

Джон Доу

$ echo $name $surname

Джон Доу

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

$ read name surname Джоя Алан Доу

$ echo $name

Джон

$ echo $surnane

Алан Доу

Следующий сценарий вызывает отдельную команду read для чтения каждой переменной:

$ cat var_test

#!/bin/sh

# var_test

echo "Имя:c"

read name

echo "Отчество:c"

read middle

echo "Фамилия:c"

read surname

В Linux…

Вместо управляющего символа с в команде echo следует указывать опцию -n:

$ cat var_test

#!/bin/sh

# var_test

echo -n "Имя:"

read name

echo -n "Отчество:"

read middle

echo -n "Фамилия:"

read surname

5.3. Команда cat

Команда cat довольно проста, но универсальна. Эту команду удобно применять как для отображения файла, так и для его создания, а также при отображении файлов, содержащих управляющие символы. Используя команду cat, следует учитывать, что процесс вывода не останавливается по достижении конца страницы – файл пролистывается до конца. Если необходимо просмотреть файл постранично, передайте вывод команды cat какой‑нибудь программе постраничной разбивки:

$ cat myfile | more

или

$ cat myfile | pg

Общий формат команды cat таков:

cat [опции] имя_файла1…имя_файла2…

Из опций команды cat в первую очередь заслуживает внимания опция -v, активизирующая режим отображения непечатаемых символов. Вывести файл myfile позволяет вот такая простая команда:

$ cat myfile

Для отображения сразу трех файлов – myfile1, myfile2 и myfile3 – нужно выполнить команду

$ cat myfile1 myfile2 myfile3

Чтобы сформировать файл bigfile, включающий содержимое файлов myfile1, myfile2 и myfile3, следует перенаправить выходной поток предыдущей команды в новый файл:

$ cat myfile1 myfile2 myfile3 >> bigfile

Если необходимо создать новый файл и ввести в него текст, не указывайте входной файл. В таком случае команда cat читает данные не из файла, а из стандартного входного потока (клавиатуры), и вам остается лишь перенаправить его в новый файл:

$ cat >> myfile

Это новый файл

$ pg myfile

Это новый файл

По завершении ввода данных нажмите [Ctrl+D].

Для просмотра управляющих символов в файле воспользуйтесь опцией -v. Следующая команда отображает содержимое файла, в котором встречаются символы (представлены как ^M):

$ cat -v life.tct

ERROR ON REC A$12^M ERROR ON REC AS31^M

5.4. Каналы

Каналом называется способ переадресации данных, при котором результаты работы одной команды передаются другой команде в виде входных данных. Канал организуется с помощью оператора |:

команда1 | команда2

В следующем примере команда ls формирует список всех файлов из текущего каталога. Этот список был бы выведен на экран, если бы не символ канала. Интерпретатор shell обнаруживает канал, перехватывает все выходные потоки команды, стоящей слева от оператора [, и направляет их команде, которая расположена справа от оператора. В данном случае утилита фильтрации grep отбирает в списке файл с именем quarter1.doc:

$ ls | grep quarter1.doc

quarter1.doc

Представим этот пример схематически:


$ ls

Канал

grep quarter1.doc

| Выходные данные команды ls

$ ls accounts.doc acc_LPSO.doc quarter1.doc

quarter1.doc quarter2.doc

При обработке строковых данных можно объединять, каналами такие мощные программы фильтрации, как потоковый редактор sed, редактор awk и утилита grep, создавая сложные критерии отбора информации. В показанной ниже командной строке команда who выводит информацию о пользователях, зарегистрированных в

данный момент в системе, а программа awk выбирает из каждой строки имя пользователя (первое поле) и идентификатор терминала (второе поле):

$ who | awk '{print $1"t"$2}'

matthew pts/0 louise pts/1

Следующая командная строка служит для вывода списка всех смонтированных файловых систем. Команда df формирует расширенный список с указанием всевозможных статистических данных об использовании каждой файловой системы. Программа awk извлекает из этого списка только первый столбец с именами файловых систем, а команда grep -v удаляет заголовок этого столбца, оставляя только имена.

$ df | awk '{print $1}' | grep -v "Filesystem"

/dev/hda5 /dev/hda8 /dev/hda6 /dev/hdb5 /dev/hdb1 /dev/hda7 /dev/hda1

С помощью редактора sed можно удалить из полученного списка повторяющуюся подстроку /dev/, оставив только имя раздела. Вот как это делается:

$ df | awk '(print $1}' | grep -v "Filesystem" | sed s'//dev///g'

hda5 hdа8 hda6 hdb6 hdb1 hda7 hda1

Команда s редактора sed предназначена для замены указанного шаблона (в данном случае /dev/; символы '/' имеют специальное назначение, поэтому защищены символами ) заданной строкой (в нашем случае это пустая строка). Флаг g означает, что замену нужно производить каждый раз, когда обнаружено совпадение, а не только первый раз.

В следующем примере команда sort сортирует строки текстового файла myfile, а результат посылается на принтер:

$ sort myfile | lp

5.5. Команда tee

Команда tee функционирует следующим образом: входные данные копируются, при этом одна копия направляется в стандартный поток вывода, а другие копии – в указанные файлы. Общий формат этой команды таков:

tee [-a] файлы

Опция -a задает добавление выводимых данных в конец файла (по умолчанию производится замена содержимого файла). Команду tee удобно применять в том случае, когда необходимо вести журнал выводимых данных или сообщений.

Рассмотрим пример. Команда who формирует список пользователей, которые зарегистрированы в данный момент в системе, а команда tee отображает этот список на экране, направляя копию в файл who.out.

$ who | tee who.out

louise pts/l May 20 12:58 (193.132.90.9)

matthew pts/0 May 20 10:18 (193.132.90.1)

$ cat who.out

louise pts/1 May 20 12:58 (193.132.90.9) matthew pts/0 May 20 10:18 (193.132.90.1)

В следующем примере команда cpio выполняет резервирование файлов из каталога /home на магнитную ленту, а список помещаемых в архив файлов фиксируется в файле tape.log. Поскольку с помощью команды cpio производится последовательное добавление данных в архив, воспользуйтесь опцией '-a' команды tee:

$ find /home -depth -print | cpio -ov -0 /dev/rmt0 | tee -a tape.log

Чтобы сообщить пользователю о том, кто именно выполнил сценарий myscript, сохраняющий выводимые данные в файле myscript.log, можно перед вызовом сценарии задать несложную команду echo:

$ echo "Сценарий myscript запушен пользователем dave" | tee -a myscript.log $ myscript | tee -a myscript.log

Можно направлять вывод нескольких команд в один и тот же файл, но не забывайте применять опцию '-a'.

$ sort myfile | tee -a accounts.log $ myscript | tee -a accounts.log

5.6. Стандартные потоки ввода, вывода и ошибок

С каждым процессом (командой, сценарием и т. п.), выполняемым в интерпретаторе shell, связан ряд открытых файлов, из которых процесс может читать свои данные, и в которые он может записывать их. Каждый из этих файлов идентифицируется числом, называемым дескриптором файла, но у первых трех файлов есть также именам которые легче запоминать:


Файл

Дескриптор

Стандартный поток ввода (stdin)

0

Стандартный поток вывода (stdout) Стандартный поток ошибок (stderr)

1

2

В действительности создается 12 открытых файлов, но, как видно из таблицы, файлы с дескрипторами 0,1 и 2 резервируются для стандартных потоков ввода, вывода и ошибок. Пользователи могут также работать с файлами, имеющими дескрипторы от 3 до 9.

5.6.1. Стандартный поток ввода

Файл стандартного потока ввода (stdin) имеет дескриптор 0. Из этого файла процессы извлекают свои входные данные. По умолчанию входной поток ассоциирован с клавиатурой (устройство /dev/tty), но чаще всего он поступает по каналу от других процессов или из обычного файла.

5.6.2. Стандартный поток вывода

Файл стандартного потока вывода (stdout) имеет дескриптор 1. В этот файл записываются все выходные данные процесса. По умолчанию данные выводятся на экран терминала (устройство /dev/tty), но их можно также перенаправить в файл или послать по каналу другому процессу.

5.6.3. Стандартный поток ошибок

Файл стандартного потока ошибок (stderr) имеет дескриптор 2. В этот файл записываются сообщения об ошибках, возникающих в ходе выполнения команды. По умолчанию сообщения об ошибках выводятся на экран терминала (устройство /dev/tty), но их также можно перенаправить в файл. Зачем же для регистрации ошибок выделять специальный файл? Дело в том, что это очень удобный способ выделения из результатов работы команды собственно выходных данных, а также хорошая возможность эффективно организовать ведение различного рода журнальных файлов.

5.7. Файловый ввод–вывод

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

Во время перенаправления стандартного потока ошибок следует указывать дескриптор файла (2). Для потоков ввода и вывода делать это не обязательно.

Таблица 5.1. Основные операторы переадресации


команда > файл

Направляет стандартный поток вывода в новый файл

команда 1> файл

Направляет стандартный поток вывода в указанный файл

команда >> файл

Направляет стандартный поток вывода в указанный файл (режим присоединения)

команда > файл 2>&1

Направляет стандартные потоки вывода и ошибок в указанный файл

команда 2> файл

Направляет стандартный поток ошибок в указанный файл

команда 2» файл

Направляет стандартный поток ошибок в указанный файл (режим присоединения)

команда >> файл 2>&1

Направляет стандартные потоки вывода и ошибок в указанный файл (режим присоединения)

команда < файл1 > файл2

Получает входные данные из первого файла и направляет выходные данные во второй файл

команда < файл

В качестве стандартного входного потока получает данные из указанного файла

команда << разделитель

Получает данные из стандартного потока ввода до тех пор, пока не встретится разделитель

команда <&m

В качестве стандартного входного потока получает данные из файла с дескриптором m

команда > &m

Направляет стандартный поток вывода в файл с дескриптором m

5.7.1. Переадресация стандартного потока вывода

Рассмотрим, как осуществляется переадресация стандартного потока вывода. В следующей командной строке из файла /etc/passwd извлекаются имена пользователей, известных в системе, полученный список сортируется по алфавиту, а результаты направляются в файл sort.out.

$ cat /etc/passwd | awk -F: '{print $1}' | sort > sort.out

Опция -f программы awk свидетельствует о том, что указанный после нее символ двоеточия является разделителем полей в файле /etc/passwd.

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

$ ls -l | grep ^d >> files.out

$ 1s account* >> files.out

В первой строке в файл files.out помещается список каталогов, а во второй -cписок файлов, имена которых начинаются со строки "account".

Для создания пустого файла нулевой длины выполните следующую команду:

$ > myfile

5.7.2. Переадресация стандартного потока ввода

Рассмотрим несколько примеров переадресации стандартного потока ввода. Чтобы из командной строки отправить пользователю электронное сообщение, которое находится в файле, следует направить файл программе mail. Посредством следующей команды пользователь louise получит сообщение, которое содержится в файле contents.txt.

$ mail louise < contents.txt

Переадресация вида команда << разделитель называется конструкцией "документ здесь". Более подробно мы поговорим о ней позже. Пока же рассмотрим общие принципы ее функционирования. Встречая в командной строке оператор «, интерпретатор shell воспринимает все данные, вводимые с клавиатуры, как входной поток, пока в отдельной строке не будет введено слово–разделитель, указанное в командной строке после оператора. Разделителем может служить любое слово. Вот как, например, можно создать файл в режиме командной строки:

$ cat >> myfile << Пока

> Привет! Я работая за терминалом $TERM

и мое имя $LOGNAME.

Пока!

Пока

$ cat myfile

Привет! Я работаю за терминалом vt100

и мое имя dave.

Пока!

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

5.7.3. Переадресация стандартного потока ошибок

При переадресации стандартного потока ошибок указывается дескриптор 2. Рассмотрим пример. Утилита grep ищет в файле missiles строку "trident":

$ grep "trident" missiles

grep: missiles: No such file or directory

Однако в текущем каталоге нет такого файла, и соответствующее сообщение об ошибке по умолчанию выводится на экран. Можно переслать все сообщения об ошибках в системную корзину (устройство /dev/null):

$ grep "trident" missiles 2> /dev/null

Теперь никакие сообщения на экране отображаться не будут.

Подобный режим работы не всегда желателен. Часто сообщения об ошибках необходимо фиксировать в файле для последующего анализа. В следующей командной строке сообщения об ошибках пересылаются в файл grep.err.

$ grep "trident" missiles 2> grep.err

$ cat grep.err

grep: missiles: No such file or directory

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

$ grep "LPSO" * 2>> account.err

$ grep "SILO" * 2>> account.err

5.7.4. Переадресация обоих выходных потоков

В одной командной строке можно последовательно переадресовывать как стандартный поток вывода, так и стандартный поток ошибок. Ниже приведен пример, в котором команда cat обрабатывает два файла, направляя вывод в файл accounts.out, а сообщения об ошибках – в файл accounts.err.

$ cat account_qtr.doc account_end.doc 1> accounts.out 2> accounts.err

$ cat accounts.out

AVBD 34HJ OUT AVFJ 31KO OUT

$ cat accounts.err

cat: account_end.doc: No such file or directory

Просмотрев файл accounts.err, обнаруживаем, что исходного файла account_end.doc не существует.

5.7.5. Объединение выходных потоков в файле

Оператор n>&m позволяет перенаправить файл с дескриптором n туда, куда направлен файл с дескриптором m. Подобных операторов в командной строке может быть несколько, в этом случае они вычисляются слева направо. Рассмотрим пример:

$ cleanup > cleanup.out 2>&1

Здесь сценарий cleanup направляет все свои выходные данные (как поток вывода, так и поток ошибок) в файл cleanup.out.

В следующем примере все результаты работы команды grep направляются в файл grep.out.

$ grep "standard" * > grep.out 2>&1

5.8. Команда exec

Команда exec заменяет текущий интерпретатор shell указанной командой. Обычно она используется для того, чтобы закрыть текущий интерпретатор и запустить другой. Но у нее есть и другое применение. Например, команда вида

exec < файл

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

exec <&-

которая закрывает стандартный входной поток (в данном случае файл). Подобный прием применяется преимущественно в сценариях, выполняющихся при выходе из системы. Более общий способ использования команды exec описан в следующем параграфе.

5.9. Применение дескрипторов файлов

Рассмотренная в предыдущем параграфе команда 'exec < файл' не только назначает файл стандартным входным потоком всех команд сценария, но и перезаписывает указатель на файл с дескриптором 0 (stdin). Восстановить этот указатель можно будет только по завершении работы сценария. Если же в сценарии предполагается продолжить чтение данных с клавиатуры, то необходимо каким‑то образом сохранить указатель на прежний входной поток. Ниже приведен небольшой сценарий, в котором демонстрируется, как это сделать.

$ cat f_desc

#!/bin/sh

# f_desc

exec 3<&0 0

read line1

read line2

exec 0<&3

echo $LINEl

echo $LINE2

Первая команда exec сохраняет указатель на стандартный входной поток (stdin) в файле с дескриптором 3 (допускается любое целое число в диапазоне от 3 до 9), а затем открывает файл stock.txt для чтения. Следующие две команды read читают из файла две строки текста. Вторая команда exec восстанавливает указатель на стандартный входной поток: теперь он связан с файлом stdin, а не stock.txt. Завершающие команды echo отображают на экране содержимое прочитанных строк, которые были сохранены в переменных line1 и line2.

Предположим, файл stock.txt содержит такой текст:

$ cat stock.txt

Crayons Assorted 34

Pencils Light 12

Ниже показаны результаты работы сценария:

$ f_desc

Crayons Assorted 34

Pencils Light 12

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

5.10. Заключение

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

ГЛАВА 6

Порядок выполнения команд

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

В этой главе рассматриваются следующие темы: в выполнение команды в зависимости от результата выполнения другой команды; в группирование команд.

Интерпретатор shell располагает операторами && и, которые группируют команды по принципу логического И/ИЛИ. Существуют также операторы () и {}, объединяющие заключенные в них команды в группу, выполняемую в текущем или порожденном интерпретаторе shell.

6.1. Оператор &&

Общий формат оператора && таков:

команда1 && команда2

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

Рассмотрим простой пример:

$ cp justice.doc justice.bak && echo "копирование прошло успешно"

копирование прошло успешно

Сообщение, заданное в команде echo, появилось на экране, значит, команда cp успешно выполнила копирование файла. А вот более практичный пример:

$ mv /apps/bin /apps/dev/bin && rm -r /apps/bin

Каталог /apps/biп с помощью команды mv перемешается в каталог /apps/dev/bin. Если перемещение завершится удачно, то исходный каталог – /apps/biп – будет удален.

В следующем примере команда sort сортирует содержимое текстового файла quarter_end.txt, записывая результат в файл quarter, sorted. Если запись прошла успешно, полученный файл выводится на печать с помощью команды lp.

$ sort quarter_end.txt > quarter.sorted && lp quarter. sorted

6.2. Оператор ||

Рассмотрим общий формат оператора | |:

команда1 || команда2

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

Приведем простой пример, иллюстрирующий применение оператора | |:

$ cp wopper.txt oops.txt || echo "копирование не выполнено"

cp: wopper.txt: No such file or directory копирование не выполнено

Операция копирования завершилась неудачно (исходного файла не существует), поэтому была выполнена команда echo.

В следующем примере из файла acc.qtr извлекаются первое и пятое поля, а результат помещается во временный файл qtr.tmp. Если по какой‑то причине извлечь нужные данные не удастся, пользователь dave получит электронное сообщение.

$ awk ' {print$1,$5}' acc.qtr > qtr.tmp || echo "Получить данные не удалось." |

mail dave

6.3. Группирование команд с помощью скобок

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

Для выполнения группы команд в текущем интерпретаторе shell следует заключить их список в фигурные скобки, разделив команды точкой с запятой:

{команда1; команда2; …}

Чтобы выполнить группу команд в порожденном интерпретаторе shell, поступите аналогичным образом, но вместо фигурных скобок поставьте круглые скобки:

(команда1; команда2; …)

Сам по себе подобный метод применяется не часто. Обычно группа команд выполняется в составе более крупных конструкций с операторами && или. Результатом работы группы команд считается результат выполнения последней команды в группе.


    Ваша оценка произведения:

Популярные книги за неделю