ГЛАВА 5 ПОСОБИЕ ПО SHELL СОДЕРЖАНИЕ ВВЕДЕНИЕ 3 5.1 КОМАНДНЫЙ ЯЗЫК SHELL 4 5.1.1 Метасимволы 5 5.1.1.1 Метасимвол для сопоставления с произвольной строкой символов: звездочка 5.1.1.2 Метасимвол для сопоставления с произвольным символом: знак вопроса (?) 5.1.1.3 Использование метасимволов * и ? для исправления ошибок ввода 8 5.1.1.4 Метасимвол для сопоставления с любым символом из набора: скобки ([]) 5.1.2 Специальные символы 10 5.1.2.1 Запуск команды в фоновом режиме: амперсанд (&) 10 5.1.2.2 Последовательное выполнение команд: точка с запятой (;) 11 5.1.2.3 Отмена специального смысла: обратная косая черта (\) 12 5.1.2.4 Отмена специального смысла: кавычки '...' и "..." 12 5.1.2.4.1 Использование кавычек для отмены смысла пробела 13 5.1.3 Переадресация ввода и вывода 14 5.1.3.1 Переадресация ввода: знак < 15 5.1.3.2 Переадресация вывода на файл: знак > 15 5.1.3.3 Добавление вывода к существующему файлу: символ >> 16 5.1.3.4 Примеры применения переадресации вывода 16 5.1.3.4.1 Команда spell 17 5.1.3.4.2 Команда sort 18 5.1.3.5 Сочетание фонового режима и переадресации вывода 18 5.1.3.6 Переадресация вывода на команду: канал (|) 19 5.1.3.7 Конвейер с командами cut и date 20 5.1.3.8 Подстановка вывода команды в качестве аргумента 22 5.1.4 Выполнение и прекращение процессов 23 5.1.4.1 Отложенный запуск процессов с помощью команд batch и at 23 5.1.4.2 Получение состояния выпоняющегося процесса 27 5.1.4.3 Прекращение активных процессов 29 5.1.4.4 Использование команды nohup 29 5.2 УПРАЖНЕНИЯ НА ИСПОЛЬЗОВАНИЕ КОМАНДНОГО ЯЗЫКА 31 5.3 ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ SHELL 32 5.3.1 Shell-программы 32 5.3.1.1 Создание простой shell-программы 32 5.3.1.2 Выполнение shell-программы 33 5.3.1.3 Создание каталога bin для выполняемых файлов 34 5.3.1.4 Предостережение об именовании shell-программ 35 5.3.2 Переменные 35 5.3.2.1 Позиционные параметры 36 5.3.2.2 Специальные параметры 38 5.3.2.3 Именованные переменные 41 5.3.2.4 Присваивание значения переменной 42 5.3.2.4.1 Использование команды read 43 5.3.2.4.2 Подстановка вывода команды в качестве значения переменной 45 5.3.2.4.3 Присваивание значений с помощью позиционных параметров 46 5.3.3 Конструкции языка программирования shell 47 5.3.3.1 Комментарии 48 5.3.3.2 Подстановка строк в команду 49 5.3.3.3 Коды возврата 50 5.3.3.3.1 Проверка кодов возврата 50 5.3.3.3.2 Использование кодов возврата с командой exit 51 5.3.3.4 Циклы 51 5.3.3.4.1 Цикл for 51 5.3.3.4.2 Цикл while 54 5.3.3.5 "Черная дыра" shell'а: /dev/null 55 5.3.3.6 Условные конструкции 56 5.3.3.6.1 Конструкция if...then 56 5.3.3.6.2 Конструкция if...then...else 57 5.3.3.6.3 Команда test 59 5.3.3.6.4 Конструкция case...esac 61 5.3.3.7 Безусловные операторы управления: команды break и continue 65 5.3.4 Программы отладки 66 5.4 МОДИФИКАЦИЯ ВХОДНОГО ОКРУЖЕНИЯ ПОЛЬЗОВАТЕЛЯ 70 5.4.1 Добавление команд в файл .profile пользователя 70 5.4.2 Установка режима работы терминала 71 5.4.3 Создание каталога rje 72 5.4.4 Использование shell-переменных 72 5.5 УПРАЖНЕНИЯ ПО ПРОГРАММИРОВАНИЮ НА ЯЗЫКЕ SHELL 76 5.6 ОТВЕТЫ К УПРАЖНЕНИЯМ 78 5.6.1 Ответы к упражнениям на использование командного языка shell 78 5.6.2 Ответы к упражнениям по программированию на языке shell 79 ВВЕДЕНИЕ В данной главе описывается, как использовать shell для выполне- ния стандартных действий: как управлять файлами, работать с их содержимым, как группировать команды в программы, которые shell может выполнять и т.д. Здесь также рассматривается, как модифи- цировать входное окружение пользователя. В первом из двух основных разделов ("Командный язык shell"), детально разбирается использование shell'а, как интерпретатора команд. В нем рассматривается, как применять команды интерпре- татора shell и символы, имеющие специальный смысл, для управле- ния файлами, переадресации стандартного ввода и вывода, выпол- нения и прекращения процессов. Во втором разделе ("Программиро- вание на языке shell") в деталях описывается использование shell'а, как языка программирования. Здесь показано, каким об- разом создавать, выполнять и отлаживать программы, составленные из команд, переменных и конструкций типа циклов и операторов case. В главе приводится много примеров. Войдя в систему UNIX, можно самому выполнить данные инструкции. Как и ранее, для того, что- бы отличать в примерах то, что вводится пользователем, от выво- да системы UNIX, используются различные типы шрифтов (например, help, опции и not found). Более детально см. в предисловии в разделе "Условные обозначения". Кроме примеров, в главе есть упражнения, которые рекомендуется выполнить для лучшго понимания рассматриваемых тем. Ответы к упражнениям приводятся в конце главы. Примечание Конкретная система UNIX может и не иметь всех рассмот- ренных в этой главе команд. При невозможности получить доступ к команде пользователю следует провести проверку этого вместе с администратором системы. Для получения общего представления о функциях shell'а, как ин терпретатора команд и языка программирования, перед чтением данной главы обратитесь к главам 1 и 4. Кроме того, в Приложе нии C дается краткое изложение командного языка shell. Для бо- лее глубокого изучения программирования на языке shell следует обратиться к руководству Команды shell и программирование (для получения информации об этом руководстве см. Список документа- ции). 5.1 КОМАНДНЫЙ ЯЗЫК SHELL В этом разделе вводятся команды и, что более важно, некоторые символы, имеющие специальный смысл, которые позволяют пользова- телю: осуществлять поиск и работать с файлами, используя со- поставление с цепочками символов; запускать процессы в фоновом режиме или в указанное время; последовательно выполнять группу команд; переадресовывать стандартный ввод и вывод; прекращать процессы. Сначала рассматриваются символы, имеющие специальный смысл для самого интерпретатора shell, а затем уже обсуждаются команды и их нотации для выполнения перечисленных выше функций. Для удобства пользователей в следующих таблицах перечисляются все символы, имеющие специальный смысл и рассматриваемые в данной главе. | +---------------+-------------------------------------------------------+ | | Символ | Функция | | +---------------+-------------------------------------------------------| | | * ? [] | метасимволы, которые обеспечивают возможность | | | | задания сокращенных имен путем их сопоставления | | | | с шаблоном | | | | | | | & | запускает команду в фоновом режиме, освобождая | | | | терминал пользователя для других задач | | | | | | | ; | отделяет команды, записанные в одной командной | | | | строке | | | | | | | \ | символы *, ?, [], &, ;, >, <, |, перед которы- | | | | ми стоит \, не несут специального смысла | | | | | | | '...' | одинарные кавычки (апострофы) отменяют смысл | | | | пробела как разделителя и специальный смысл | | | | всех остальных символов | | | | | | | "..." | двойные кавычки отменяют смысл пробела как | | | | разделителя и специальный смысл всех остальных | | | | символов, за исключением $ и ` | | +---------------+-------------------------------------------------------+ | +---------------+-------------------------------------------------------+ | | Символ | Функция | +---------------+------------------------------------------------------- | | > | переназначает вывод команды в файл, заменяя | | | содержимое файла | | < | переназначает ввод на файл | | | | | >> | переназначает вывод команды в файл, добавляя | | | его в конец существующего файла | | | | | | | создает канал вывода, позволяющий результат | | | одной команды использовать в качестве ввода | | | другой | | `...` | заключение в обратные кавычки позволяет под- | | | ставлять вывод команды в качестве аргумента в | | | командную строку | | $ | используется с переменными, определяемыми | | | пользователем, и позиционными параметрами; | | | используется и как символ приглашения shell, | | | задаваемый по умолчанию | | +---------------+-------------------------------------------------------+ 5.1.1 Метасимволы Метасимволы это специальные символы, которые используются для сопоставления имен файлов или их частей, упрощая тем самым за- дание файлов или группы файлов в качестве аргументов команд. (Файлы, имена которых генерируются с помощью этих метасимволов, должны уже существовать.) Это называется расширением имени фай- ла. Например, пользователь может сослаться на все файлы с име- нами, содержащими букву "a", все имена файлов, состоящие из пя- ти букв, и т.д. Здесь рассматриваются метасимволы * (звездоч- ка), ? (знак вопроса) и [] (скобки). 5.1.1.1 Метасимвол для сопоставления с произвольной строкой символов: звездочка (*) Звездочка (*) задает сопоставление с произвольной строкой сим- волов, включая строку нулевой длины (пустую строку). Ее можно использовать для указания как всего имени файла, так и его час- ти. Звездочка, без каких-либо других символов, используется для обозначения всех имен файлов и каталогов текущего каталога. Чтобы проиллюстрировать действие метасимвола *, укажем его в качестве аргумента в команде echo: |echo * Команда echo выводит свои аргументы на экран. Заметим, что от- ветом системы на команду echo * будет список содержимого теку щего каталога пользователя, причем имена файлов отображаются горизонтально в строках, а не по вертикали колонками, как при выполнении команды ls. В таблице приводится краткое описание синтаксиса и возможностей команды echo. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | echo - вывести все аргументы | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | echo отсутствуют любой(ые) символ(ы) | | +-----------------------------------------------------------------------| | | Описание: Команда echo выводит аргументы, отделяемые | | | друг от друга пробелами, на стандартный вывод. | | | | | | Примечания: При программировании на языке shell команда echo | | | используется для вывода указаний, переадресации | | | слов или данных в файл и для включения данных в | | | команду. Все эти применения команды будут рассматри- | | | ваться ниже в этой главе. | | +-----------------------------------------------------------------------+ Предостережение Звездочка является "могущественным" символом. Например, если ввести rm *, то это приведет к уничтожению всех файлов текущего каталога. Будьте внимательны при ис- пользовании *. Рассмотрим другой пример. Допустим пользователь написал нес- колько докладов и назвал их report, report1, report1a, re- port1b.01, report25 и report316. Если задать report1*, тем са- мым можно обратиться ко всем файлам, имена которых содержат в качестве составной части report. Чтобы определить, какие докла- ды написаны, пользователь может выполнить команду ls и получить список всех файлов с именами, начинающимися со строки report: |$ ls report* |report |report1 |report1a |report1b.01 |report25 |report316 |$ По метасимволу * после report подбираются всевозможные комбина- ции символов, в том числе пустая комбинация. Заметим, что мета- символ * располагает файлы в числовом и алфавитном порядке. Со- держимое этих файлов в том же порядке быстро и легко можно вы- вести с помощью команды: |pr report* Теперь выполним другое упражнение. Выберем символ, который яв ляется общим для всех имен файлов текущего каталога, например, строчную букву "a". Затем потребуем вывести список тех файлов, в имени которых есть этот символ. Если выбрана строчная буква "a", следует ввести командную строку: |ls *a* В ответ система выведет имена всех файлов текущего каталога, содержащие строчную букву "a". Звездочка * может сопоставляться с символами в любой части име- ни файла. Например, если известно, что несколько файлов имеют одинаковые первые и последние буквы имени, можно вывести их список, взяв этот факт за основу. Командная строка в этом слу- чае может иметь примерно такой вид: |ls F*E Ответом системы будет список имен файлов, которые начинаются с F и заканчиваются на E, и располагаться он будет в таком поряд- ке: |F123E |FATE |FE |Fig3.4E Порядок определяется последовательностью сортировки в коде AS- CII: (1) числа; (2) прописные буквы; (3) строчные буквы. 5.1.1.2 Метасимвол для сопоставления с произвольным символом: знак вопроса (?) Метасимвол ? производит сопоставление с любым отдельным симво лом в имени файла. Пусть пользователь пишет книгу, содержащую 18 глав, и хочет получить список тех из них (с номерами до 9), которые он закончил. Для этого следует использовать команду ls с метасимволом ? после цепочки символов chapter: |$ ls chapter? |chapter1 |chapter2 |chapter5 |chapter9 |$ Система отвечает выводом списка имен файлов, которые после це- почки символов chapter содержат ровно один символ. Метасимвол ? производит сопоставление с единственным символом, но его можно использовать в имени файла несколько раз. Чтобы вывести список остальных глав книги, необходимо ввести команду: |ls chapter?? Конечно, если желательно вывести список всех глав, содержащихся в текущем каталоге, используют метасимвол *: |ls chapter* 5.1.1.3 Использование метасимволов * и ? для исправления ошибок ввода Предположим пользователь для переименования файла использует команду mv(1) и делает ошибку при ее наборе, вводя в имени фай- ла символ, который не отображается на экране его терминала. Система включает этот непечатаемый символ в имя файла и впос- ледствии требует этот символ, как часть имени файла. Если не включить этот символ в командную строку при вводе имени файла, система выдаст сообщение об ошибке. Чтобы сопоставить имя файла с именем, содержащим непечатаемый символ, и затем переименовать его, присвоив корректное имя, можно использовать метасимвол * или ?. Выполните следующий пример 1. Создайте очень короткий файл с именем proba. 2. Введите : mv proba proba<^g>1 (Вспомните, чтобы ввести <^g>, необходимо, удерживая в нажатом состоянии клавишу CONTROL, нажать клавишу g.) 3. Введите: ls proba1 Система ответит сообщением об ошибке: |$ ls proba1 |proba1 not found: no such file or directory 4. Введите: ls proba?1 Система ответит выводом имени файла proba1, включающего непечатаемый символ, подтверждая тем самым, что файл существует. После этого снова используйте метасимвол ? для исправления имени файла: |$ mv proba?1 proba1 |$ ls proba1 |proba1 |$ 5.1.1.4 Метасимвол для сопоставления с любым символом из набо- ра: скобки ([]) Для сопоставления с одним из нескольких возможных символов, ко- торый может находиться в одной из позиций имени файла, исполь- зуются квадратные скобки []. Например, если включить набор сим- волов [crf] в шаблон имени файла, то shell будет искать имена файлов, которые имеют в указанной позиции букву "c", букву "r" или букву "f", что показано в следующем примере: |$ ls [crf]at |cat |fat |rat |$ Эта команда выводит все имена файлов, начинающиеся на букву "c", "r" или "f" и заканчивающиеся на буквы "at". Символы, ко- торые группируются внутри скобок, называются "классом симво- лов". Скобки могут использоваться и для указания диапазона символов (как цифр, так и букв). Например, если указать chapter[1-5] shell выберет все имена файлов от chapter1 до chapter5. Таким образом можно обращаться одновременно к нескольким файлам, на чинающимся на chapter. Выполним следующую команду : |$ pr chapter[2-4] Эта команда выведет содержимое файлов chapter2, chapter3 и chapter4 на терминал именно в таком порядке. Класс символов может определять и диапазон букв. Если задать [A-Z], shell будет искать только прописные буквы, если [a-z] - только строчные. Краткие сведения о применении метасимволов сведены в таблицу. | +--------------+-------------------------------------------------------+ | | Символ | Функция | | +--------------+-------------------------------------------------------| | | * | сопоставление с любой цепочкой символов, включая | | | | и пустую цепочку | | | | | | | ? | сопоставление с любым отдельным символом | | | | | | | [] | сопоставление с одним из символов, указанных в | | | | скобках | | | | | | | [ - ] | сопоставление с любым символом указанного | | | | диапазона | | +--------------+-------------------------------------------------------+ 5.1.2 Специальные символы В языке shell существуют и другие специальные символы, которые выполняют ряд полезных функций. Часть этих дополнительных спе- циальных символов рассматривается в данном разделе, другие - в разделе "Переадресация ввода и вывода". 5.1.2.1 Запуск команды в фоновом режиме: амперсанд (&) Некоторые команды shell выполняются довольно долго. Для запуска команды в фоновом режиме служит знак амперсанда (&); это позво- ляет освободить терминал для выполнения других задач. Общий формат для запуска команды в фоновом режиме: |команда & Примечание В фоновом режиме не следует запускать интерактивные ко- манды, например, команду read (см. "Использование ко- манды read" в данной главе). В представленном ниже примере shell выполняет достаточно дли- тельный поиск в фоновом режиме. (Команда grep(1) осуществляет поиск цепочки символов пожелания в файле account.) Обратите внимание на & (последний символ строки): |$ grep пожелания account & |21940 |$ Когда команда запускается в фоновом режиме, система UNIX выво- дит номер процесса; в примере таким номером является 21940. Этот номер можно использовать для прекращения выполнения фоно- вой команды. (Прекращение выполнения процессов рассматривается в разделе "Выполнение и прекращение процессов".) Приглашение на последней строке означает, что терминал свободен и ожидает вво- да команд пользователя, а команда grep запущена в фоновом режи- ме. Запуск команды в фоновом режиме влияет только на доступность терминала пользователя, но не оказывает никакого действия на вывод команды. Независимо от того, выполняется команда в фон вом режиме или нет, ее вывод направляется на экран терминала, если только не осуществлена переадресация вывода на файл. (Бо- лее детально см. ниже в данной главе раздел "Переадресация вы- вода".) Если пользователь хочет, чтобы продолжалось выполнение в фоно- вом режиме после выхода пользователя из системы, следует вво- дить команду вместе с nohup(1). (Эта команда рассматривается ниже в данной же главе в разделе "Использование команды no- hup".) 5.1.2.2 Последовательное выполнение команд: точка с запятой (;) В одной строке можно задавать две или более команд, отделяя их друг от друга точкой с запятой (;): |команда1; команда2; команда3 Система UNIX выполняет команды в порядке их появления в строке и направляет их вывод на экран. Этот процесс называется после- довательным выполнением. Чтобы увидеть, как действует точка с запятой (;), выполните следующее упражнение. Сначала введите |cd; pwd; ls Shell выполняет эти команды последовательно: 1. Команда cd переводит пользователя в его входной каталог. 2. Команда pwd выводит полное маршрутное имя текущего ката лога. 3. Команда ls выводит список файлов текущего каталога. Если нежелательно, чтобы ответы системы при выполнении этих ко- манд появлялись на экране, переадресуйте вывод (см. раздел "Пе- реадресация вывода"). 5.1.2.3 Отмена специального смысла: обратная косая черта (\) Специальные символы, перед которыми стоит обратная косая черта (\), не несут специального смысла. Продемонстрируем это на сле- дующем примере. Создадим файл из двух строк с именем proba, ко- торый содержит такой текст: |Все игры помечены |символом * Используем для поиска в файле символа * команду grep: |$ grep \* proba |символом * |$ Команда grep находит звездочку * в тексте и выводит строку, в которой она содержится. Если бы в команде grep не было символа \, звездочка рассматривалась бы интерпретатором shell как мета- символ и выполнялось бы сопоставление со всеми именами файлов текущего каталога. 5.1.2.4 Отмена специального смысла: кавычки '...' и "..." Другой способ отмены "специальности" символа реализуется с по- мощью кавычек. Одинарные кавычки (апострофы) отменяют смысл пробела как разделителя и специальный смысл всех остальных сим волов. Двойные кавычки отменяют смысл пробела как разделителя и специальный смысл символов, за исключением $ и ` (обратная ка- вычка). Часто проще и короче использовать кавычки, чем приме- нять обратную косую черту. Например, если файл с именем proba дополнительно содержит стро- ку |Вас это интересует? Интересует??? то команду grep для поиска строки с тремя знаками вопроса можно использовать в следующем виде: |$ grep '???' proba |Вас это интересует? Интересует??? |$ Если же ввести команду в виде |grep ??? proba три знака вопроса воспринимались бы интерпретатором shell как метасимволы, в результате чего сопоставлялись бы все имена фай- лов из трех символов. 5.1.2.4.1 Использование кавычек для отмены смысла пробела Обычно, использование кавычек направлено на отмену специального смысла пробела. Shell воспринимает пробел в командной строке, как разделитель между аргументами команды. Как апострофы, так и двойные кавычки позволяют отменять этот смысл пробела. Например, чтобы определить местонахождение двух или более слов, которые вместе появляются в тексте, следует оформить эти слова как один аргумент в команде grep, заключив их в кавычки. Так, для нахождения пары слов Все игры в файле proba необходимо ввести следующую командную строку: |$ grep 'Все игры' proba |Все игры помечены |$ Команда grep находит цепочку символов Все игры и выводит стро- ку, которая ее содержит. Подумайте, что произойдет, если не взять в кавычки цепочку символов? Возможность отменять специальний смысл пробела особенно полезна при использовании команды banner(1). Эта команда выводит сооб- щение на экран терминала плакатными буквами. При выполнении команды banner указывают сообщение, состоящее из одного или нескольких аргументов (в данном случае обычно слов), разделяемых в командной строке пробелами. Команда banner будет использовать эти пробелы, чтобы разделять аргументы и выводить их на отдельных строках. Для вывода нескольких аргументов на одной строке их следует вместе заключить в кавычки. Например, чтобы послать поздравление с днем рождения другому пользователю, введите: |banner Happy birthday to you! Команда выведет сообщение в четыре строки. Для того, чтобы вы- вести это же сообщение в три строки, следует набрать команду в таком виде: |banner Happy birthday "to you!" Заметьте, что слова "to" и "you!" теперь появляются на одной строке. Пробел между ними потерял свой смысл разделителя. В таблице приводится краткое описание синтаксиса и возможностей команды banner. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | banner - вывести плакатными буквами | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | banner отсутствуют символы | | +-----------------------------------------------------------------------| | | Описание: Команда banner выводит цепочки длиной до 10 символов | | | плакатными буквами. | | | | | | Примечание: Ниже в этой главе будет показано, каким образом | | | переадресовать вывод команды banner на файл, чтобы | | | использовать его, как объявление. | | +-----------------------------------------------------------------------+ 5.1.3 Переадресация ввода и вывода В системе UNIX некоторые команды ожидают получения входных дан- ных с клавиатуры (стандартный ввод) и большинство команд выво- дят результаты своей работы на терминал (стандартный вывод). Однако система позволяет пользователям переназначать стандарт- ные ввод и вывод на другие файлы или программы. Эта процедура известна под названием переадресации. С помощью переадресации пользователь может указать интерпретатору shell: ввести данные из файла, а не с клавиатуры послать результаты в файл, а не на терминал использовать программу как источник данных для другой программы Для переадресации ввода/вывода используются: знак меньше (<), знак больше (>), два знака больше (>>) и канал (|). 5.1.3.1 Переадресация ввода: знак < Чтобы переадресовать ввод на файл, необходимо в командной стро- ке указать имя файла после знака меньше (<): |команда < файл Допустим, пользователь собирается с помощью команды mail(1) (см. гл. 6), послать сообщение пользователю с входным именем marina, а само сообщение уже находится в файле с именем report. Повторного ввода сообщения можно избежать, если в качестве ис- точника ввода сообщения указать имя файла: |mail marina < report 5.1.3.2 Переадресация вывода на файл: знак > Для переадресации вывода на файл следует в командной строке указать имя файла после знака больше (>): |команда > файл Предостережение Shell не допускает наличия двух файлов с одинаковыми именами. Если осуществляется переадресация вывода в уже существующий файл, shell уничтожит первоначальное с держимое этого файла, заменит его на вывод команды. Shell не предупреждает о выполнении записи в существующий файл. Перед выполнением переадресации вывода команды на определенный файл убедитесь, что файл с таким именем еще не существует (если Вы против его потери). Чтобы убедиться в том, что файла с именем, которое планируется использовать для переадресации, нет, запустите команду ls, ука- зав предполагаемое имя файла в качестве аргумента. Если файл с таким именем существует, команда ls выведет его имя; в против- ном случае будет выдано сообщение о том, что файл в текущем ка- талоге не найден. Например, проверка существования файлов temp и junk могла бы дать следующий результат: |$ ls temp |temp |$ ls junk |junk not found: no such file or directory |$ Это означает, что новому файлу вывода можно присвоить имя junk, но нельзя - имя temp, если думать о дальнейшем сохранении со- держимого файла temp. 5.1.3.3 Добавление вывода к существующему файлу: символ >> С целью сохранения содержания существующего файла можно исполь- зовать двойной символ переадресации (>>): |команда >> файл В данном случае вывод команды добавляется к концу файла. Если файл не существует, то он при использовании символа >> создает ся. В следующем примере показано, как добавить вывод команды cat к существующему файлу. Сначала команда cat выполняется для того, чтобы без переадресации вывода показать содержимое файлов. За- тем, при выполнении команды cat proba2 с переадресацией вывода на файл proba1, содержимое файла proba2 добавляется после пос- ледней строки файла proba1. И, наконец, просматривается допол- ненный файл. |$ cat proba1 |Это первая строка файла proba1. |Здравствуйте |Это последняя строка файла proba1. |$ cat proba2 |Это начало файла proba2. |Здравствуйте. |Это конец файла proba2. |$ cat proba2 >> proba1 |$ cat proba1 |Это первая строка файла proba1. |Здравствуйте. |Это последняя строка файла proba1. |Это начало файла proba2. |Здравствуйте. |Это конец файла proba2. |$ 5.1.3.4 Примеры применения переадресации вывода Переадресация вывода полезна в тех случаях, когда пользователю не нужно, чтобы результат немедленно появлялся на экране, или когда результат желательно сохранить. Но она особенно полезна тогда, когда запущены команды, которые выполняют канцелярскую работу с текстовыми файлами. Двумя такими командами являются команды spell и sort 5.1.3.4.1 Команда spell Команда spell выполняет сравнение каждого слова файла с элемен- тами своего внутреннего словаря и выводит на экран список всех потенциальных орфографических ошибок. Если команда spell не имеет какого-либо слова в словаре (например, имени человека), она будет расценивать это тоже как орфографическую ошибку. Команда spell, запущенная для длинного текстового файла, может потребовать для выполнения много времени и сформировать такой длинный список ошибок, который не поместится на экране. Команда выводит результат своей работы весь сразу и, если список не по- мещается на экране, она прокручивает его по экрану снизу вверх пока не будет выдан весь результат. Длинный список ошибок будет быстро перемещаться по экрану, и его будет трудно читать. Эту проблему можно обойти, если применить переадресацию вывода команды spell на файл. В следующем примере команда spell прове- ряет файл с именем memo, а список ошибочных слов помещает в файл misspell: |$ spell memo > misspell В таблице приводится краткое описание синтаксиса и возможностей команды spell. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | spell - найти орфографические ошибки | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | spell возможны* файл | | +-----------------------------------------------------------------------| | | Описание: Команда spell берет слова из указанного файла или | | | файлов и ищет их в орфографическом словаре. Слова, | | | которых нет в этом словаре, выводятся на терминал. | | | | | | Опции: Команда spell имеет несколько опций, одна из которых | | | служит для проверки в соответствии с британским | | | правописанием. | | | | | | Примечание: Список слов с орфографическими ошибками может быть | | | переадресован на файл. | | +-----------------------------------------------------------------------+ * Описание всех имеющихся опций и их действие см. в разд. spell(1) Справочника пользователя. 5.1.3.4.2 Команда sort Команда sort располагает строки указанного файла в алфавитном порядке (более подробные сведения см. в гл. 3). Поскольку поль- зователи обычно хотят сохранить упорядоченный по алфавиту файл, переадресация вывода существенно увеличивает значимость этой команды. Будьте внимательны при выборе нового имени для файла, в который будет направлен вывод команды sort (упорядоченный по алфавиту список). При выполнении команды sort shell в первую очередь очищает файл, в который переадресуется вывод. Затем он выполня- ет команду sort и помещает ее вывод в пустой файл. Если ввести: |sort list > list shell очистит файл list, а затем проведет сортировку уже пусто- го файла с выводом результата в файл list. 5.1.3.5 Сочетание фонового режима и переадресации вывода Запуск команды в фоновом режиме не оказывает действия на вывод команды; если он не переадресован, то всегда направляется на экран терминала. Если пользователь выполняет на терминале неко- торые действия в то время, когда команда работает в фоновом ре- жиме, эти действия будут прерваны при выводе результатов коман ды на экран. Но если переадресовать вывод команды на файл, та- кого нарушения работы пользователя за терминалом не происходит. Например, в разделе "Специальные символы" было показано, как выполнить команду grep в фоновом режиме с помощью амперсанда (&). Теперь предположим, что необходимо найти слово конь в фай- ле с именем vopros. Запустим команду grep в фоновом режиме и переадресуем ее вывод на файл testfile: |$ grep конь vopros > testfile & После этого можно использовать терминал для другой работы, а проверить файл testfile по ее завершении. 5.1.3.6 Переадресация вывода на команду: канал (|) Символ | обозначает канал. Каналы являются мощным инструментом, они позволяют вывод одной команды использовать в качестве ввода другой, не создавая при этом временных файлов. Созданная таким образом командная строка, содержащая несколько команд, называ ется конвейером. Конвейер имеет следующий общий формат: |команда1 | команда2 | команда3... Вывод команды команда1 используется как ввод для команды коман- да2. Выход команды команда2 затем служит в качестве ввода для команды команда3. Чтобы понять эффективность и мощность конвейера, рассмотрим различие между двумя методами, дающими одинаковый результат. Метод переадресации ввода/вывода: запустите команду и переадресуйте ее вывод на временный файл. Затем запус- тите вторую команду, которая использует содержимое вре- менного файла в качестве своего ввода. Наконец, удалите временный файл после завершения второй команды. Метод конвейера: запустите команду, направив ее вывод прямо на другую команду. Предположим, пользователь хочет послать сообщение с поздравле- нием с днем рождения плакатными буквами пользователю с входным именем david. Сделать это без конвейера можно в три шага. Необ- ходимо: 1. Ввести команду banner и переадресовать ее вывод на вре- менный файл: |banner happy birthday > message.tmp 2. Ввести команду mail, используя файл message.tmp в качест- ве его ввода: |mail david < message.tmp 3. Удалить временный файл: |rm message.tmp Однако, используя конвейер, это можно сделать за один шаг: |banner happy birthday | mail david 5.1.3.7 Конвейер с командами cut и date Команды cut и date служат хорошим примером того, как конвейер может расширить возможности отдельных команд. Команда cut поз- воляет выделять часть в каждой строке файла. Она отыскивает символы, в указанной части строки, и выводит их. Для задания позиции в строке используется опция -c, а требуемая часть стро- ки определяется числом позиций, которое она занимает в строке, отсчитываемых от левого края строки. Пусть, например, необходимо из файла с именем birthday вывести только даты. Файл содержит следующий список: |Anne 12/26 |Klaus 7/4 |Mary 10/18 |Peter 11/9 |Nandy 4/23 |Sam 8/12 Даты дней рождения находятся между девятой и тринадцатой пози- циями каждой строки. Чтобы вывести их, выполним команду: |$ cut -c9-13 birthday |12/26 |7/4 |10/18 |11/9 |4/23 |8/12 В таблице приводится краткое описание синтаксиса и возможностей команды cut. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | cut - выделить выбранные поля каждой строки файла | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | cut -cсписок файл | | | -fсписок[-d] | | +-----------------------------------------------------------------------| | | Описание: Команда cut выделяет колонки из таблицы или поля из | | | каждой строки файла. | | | | | | Опции: -c выводит символы, находящиеся в номерах позиций, | | | которые отсчитываются от левого края строки. | | | Диапазон позиций, например, с 1 по 9, определяется| | | как -c1-9. | | | | | | -f выводит поле от позиции, отсчитываемой от левого | | | края строки, до ограничителя, определяемого | | | опцией -d. | | | | | | -d задает ограничитель поля для опции -f. По умолча- | | | нию ограничителем служит пробел. Если, например, | | | ограничителем является двоеточие, то опция зада- | | | ется в виде -d:. | | Примечание: Если пользователь считает команду cut полезной, он | | может дополнительно обратиться к командам paste и | | split. -------+ Команда cut обычно выполняется над файлом. Однако, механизм ка- налов позволяет выполнять ее и над выводом другой команды. Это удобно, когда пользователя интересует только часть информации вывода, генерируемого другой командой. Например, можно вывести только время, хотя команда date выдает и день недели, и дату, и время: |$ date |Sat Dec 27 13:12:32 EST 1989 |$ Заметим, что время указывается в строке между двенадцатой и де- вятнадцатой позициями. Вывод времени (без даты) можно организо- вать, передавая вывод команды date в качестве ввода команды cut, в которой, в опции -c указано поле позиций 12-19. Команд- ная строка и результат ее выполнения, в этом случае, будут иметь вид: |$ date | cut -c12-19 |13:14:56 |$ В таблице приводится краткое описание синтаксиса и возможностей команды date. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | date - вывести дату и время | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | date +%m%d%y возможны | | | +%H%%M%S | | +-----------------------------------------------------------------------| | | Описание: Команда date выводит на терминал текущие дату и время.| | | | | | Опции: Следующие за +% значения, которые соответствуют m | | | (для месяца), d (для дня), y (для года), H (для ча- | | | сов), M (для минут) и S (для секунд), будут выданы на | | | терминал. Сюда же можно добавить пояснения, например: | | | | | | date '+%H:%M is the time' | | | | | | Примечания: Если пользователь работает на небольшой системе, в | | | которой он одновременно является и пользователем, и | | | администратором, ему может быть разрешена установка | | | даты и времени, которая выполняется с помощью допол- | | | нительных аргументов в команде date. Если же он рабо- | | | тает в многопользовательской среде, использование этих| | | аргументов в команде date разрешается только админи- | | стратору системы. | +-----------------------------------------------------------------------+ * Описание всех имеющихся опций и их действие см. в разд. date(1) Справочника пользователя. 5.1.3.8 Подстановка вывода команды в качестве аргумента Вывод любой команды может быть взят и использован в качестве аргументов командной строки. Для этого команду необходимо зак- лючить в обратные кавычки (`...`) и поместить в то место ко- мандной строки, где ее вывод должен трактоваться как аргумент. Этот прием известен под названием "подстановки результата вы- полнения команды". Например, вывод конвейера команд date и cut можно использовать в качестве аргумента для команды banner, введя следующую ко- мандную строку: |$ banner `date | cut -c12-19` Обратите внимание на результат: система выведет текущее время плакатными буквами. В разделе "Программирование на языке shell" этой же главы будет показано, как использовать вывод командной строки в качестве значения переменной. 5.1.4 Выполнение и прекращение процессов В этом разделе обсуждаются следующие темы: как запланировать запуск команд с помощью batch или at; как получить информацию о состоянии активных процессов; как прекратить активный процесс; как продолжить выполнение фонового процесса после свое- го выхода из системы. 5.1.4.1 Отложенный запуск процессов с помощью команд batch и at Команды batch и at позволяют пользователю выполнить отложенный запуск команды или последовательности команд. При использовании команды batch момент запуска команд определяет система, а для команды at этот момент устанавливает пользователь. Обе команды предполагают ввод с устройства стандартного ввода (терминала). Список вводимых с терминала команд должен завершаться нажатием <^d>. Команда batch удобна в тех случаях, когда запускаемый процесс или shell-программа требуют много времени. Эта команда создает системе пакетное задание, содержащее команды подлежащие выпол- нению. Задание помещается в очередь и запускается тогда, когда система приступает к обслуживанию соответствующего уровня прио- ритета. Это избавляет систему от необходимости быстрого ответа на ввод и делает ее "учтивой" по отношению к другим пользовате- лям. Общий формат команды batch: |batch |первая команда | . | . | . |последняя команда |<^d> Если с batch выполняется лишь одна команда, то формат может быть таким: |batch команда |<^d> В следующем примере batch используется для выполнения команды grep в удобное для системы время. Команда grep осуществляет по иск всех файлов текущего каталога, имена которых начинаются с dollar, и переадресует свой вывод на файл dol.file. |$ batch grep dollar* > dol.file |<^d> |job 155223141.b at Sun Dec 7 11:14:54 1989 |$ После приема задания, определяемого командой batch, система от- вечает выводом номера задания, даты и времени. Этот номер зада- ния не является аналогом номера процесса, который создает сис- тема при запуске команды в фоновом режиме. В таблице приводится краткое описание синтаксиса и возможностей команды batch. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | batch - осуществить отложенное выполнение команд | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | batch отсутствуют командные_строки | | +-----------------------------------------------------------------------| | | Описание: Команда batch создает пакетное задание, которое поме- | | | щается в очередь и выполняется тогда, когда система | | | приступает к обслуживанию соответствующего уровня | | | приоритета. | | | | | | Примечание: Список команд должен завершаться <^d>. | | +-----------------------------------------------------------------------+ Команда at позволяет пользователю указывать точное время выпол нения команд. Общий формат команды at: |at время |первая команда | | . | . |последняя команда |<^d> Аргумент время состоит из значения дневного времени и, если да- та не является текущей, требуемой даты. В следующем примере, демонстрируется использование команды at, для передачи пользователю с входным именем emily поздравления с днем рождения, плакатными буквами: |$ at 8:15 Feb 27 |banner happy birthday | mail emily |<^d> |job 453400603.a at Thurs Feb 27 08:15:00 1989 |$ Обратите внимание, что команда at, как и команда batch, отвеча ет выводом номера задания, даты и времени. Если появилась потребность отменить выполнение команд, ожидаю- щих в очереди заданий, формируемой командой batch или at, то это можно сделать, с помощью команды at с опцией -r, указав но- мер задания. Общий формат такой команды: |at -r номер_задания Чтобы отменить предыдущее задание на передачу поздравления с днем рождения, сформированное по команде at, следует ввести: |at -r 453400603.a Если пользователь забыл номер задания, с помощью команды at -l можно получить список текущих заданий, имеющихся в очередях ко- манд batch и at, что показано в следующем примере: |$ at -l |user = mylogin 168302040.a at Sat Nov 29 13:00:00 1989 |user = mylogin 453400603.a at Fri Feb 27 08:15:00 1990 Заметьте, что система выводит номер задания и время, когда оно будет запущено. Используя команду at, можно послать самому себе сообщение о наступлении времени обеда (пусть для определенности само сооб- щение с напоминанием находится в файле memo). После этого можно проверить очередь командой at с опцией -l: |$ at 12:00 pm |mail mylogin < memo |<^d> |job 263131754.a at Jun 30 12:00:00 1989 |$ at -l |user = mylogin 263131754.a at Jun 30 12:00:00 1989 |$ В таблице приводится краткое описание синтаксиса и возможностей команды at. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | at - выполнить команды в указанное время | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | at -r время (дата) | | | -l номер_задания | | +-----------------------------------------------------------------------| | | Описание: Выполняет команды в указанное время. Для задания | | | времени можно использовать от одной до четырех | | | числовых величин и определять время как до полудня, | | | так и после полудня. Чтобы указать дату, следует | | | задать название месяца и далее число. Если задание | | | запускается в текущий день, указывать дату нет | | | необходимости. Сведения о других временных парамет- | | | рах, задаваемых по умолчанию, содержатся в разд. | | | at(1) Справочника пользователя. | | | | | | Опции: -r указанная вместе с номером задания, удаляет | | | предварительно запланированное задание | | | | | | -l выводит номер задания и состояние для каждого | | | из запланированных заданий в очередях команд | | | batch и at (опция используется в команде at | | без аргументов) | | | | Примечания: Несколько примеров того, как указывать время и | | дату в команде at: | | | | at 08:15am Feb 27 | | | | at 5:14pm Sept 24 | +-----------------------------------------------------------------------+ 5.1.4.2 Получение состояния выпоняющегося процесса Команда ps выводит состояния всех процессов, которые выполняют- ся в текущий момент. Команду ps можно использовать, например, для определения состояний всех процессов, запущенных в фоновом режиме с помощью & (описано выше в разделе "Специальные симво- лы"). В следующем разделе ("Прекращение активных процессов") рассмат- ривается, как номер PID (идентификатор процесса) может приме- няться для прекращения выполнения команды. Идентификатором про- цесса PID является число в диапазоне от 1 до 30000, которое система UNIX назначает каждому активному процессу. В показанном ниже примере, сначала запускается команда grep в фоновом режиме, а затем вводится команда ps. Ответ системы со- держит идентификатор процесса (PID) и идентификационный номер терминала (TTY), а также суммарное время выполнения каждого процесса (TIME) и имя команды, которой процесс запущен (COM- MAND). |$ grep rab* > temp & |28223 |$ ps |PID TTY TIME COMMAND |28124 tty1 00:00 sh |28223 tty1 00:04 grep |28224 tty1 00:04 ps |$ Следует отметить, что система выводит номер PID команды grep и всех остальных развивающихся процессов: самой команды ps и ко- манды sh (shell), которая запускается при входе пользователя в систему. Программа sh, реализующая функции shell'а, осуществля ет интерпретацию команд; она обсуждается в гл. 1 и 4. В таблице приводится краткое описание синтаксиса и возможностей команды ps. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | ps - вывести состояние процесса | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | ps несколько отсутствуют | | +-----------------------------------------------------------------------| | | Описание: Команда ps выводит информацию об активных процессах. | | | | | | Опции: Возможны несколько опций. Если ни одна не определена, | | | команда ps выводит состояние всех активных процессов, | | | запущенных пользователем. | | | | | | Примечание: Команда выводит PID (идентификатор процесса), который | | | используется при прекращении процесса командой kill. | | +-----------------------------------------------------------------------+ * Описание всех имеющихся опций и их действие см. в разд. ps(1) Справочника пользователя. 5.1.4.3 Прекращение активных процессов Для прекращения активных процессов используется команда kill. Общий формат команды kill: |kill PID Команду kill можно применять для прекращения процессов, запу- щенных в фоновом режиме. Запомните, что фоновые процессы нельзя прекратить нажатием клавиши BREAK или DELETE. В следующем примере показано, как можно прекратить команду grep (см. предыдущий пример), которая была запущена на выполнение в фоновом режиме: |$ kill 28223 |28223 Terminated |$ Обратите внимание на то, что система отвечает сообщением и вы- водит приглашение; это говорит о прекращении процесса. Если система не может найти указанный номер PID, она выводит сообще- ние об ошибке: |kill: 28225: no such process В таблице ниже приводится краткое описание синтаксиса и возмож- ностей команды kill. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | kill - прекратить процесс | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | kill возможны номер_задания или PID| | +-----------------------------------------------------------------------| | | Описание: Команда kill прекращает процесс, определяемый номером | | | PID. | | | | | | Примечание: Описание всех имеющихся опций и их действие см. в | | | разд. kill(1) Справочника пользователя. | | +-----------------------------------------------------------------------+ 5.1.4.4 Использование команды nohup После выхода пользователя из системы все его процессы прекраща- ются. Если же он хочет, чтобы и после выхода из системы его процессы продолжались, ему необходимо запускать фоновую команду под управлением команды nohup. Команда nohup имеет следующий формат: |nohup команда & Заметим, что команда nohup помещается перед командой, запускае- мой в фоновом режиме. Предположим, пользователь собирается запустить команду grep для поиска в текущем каталоге всех файлов, имеющих в имени цепочку rab, с переадресацией ее вывода на файл с именем rab.list, а затем сразу же выйти из системы. Для этого ему следует ввести командную строку: |nohup grep rab* > rab.list & Команду nohup можно отменить с помощью команды kill. В таблице приводится краткое описание синтаксиса и возможностей команды nohup. | +-----------------------------------------------------------------------+ | | Краткое описание команды | | | | | | nohup - предотвратить прекращение выполнения команды | | | при выходе пользователя из системы или разрыве | | | связи | | +-----------------------------------------------------------------------| | | команда опции аргументы | | +-----------------------------------------------------------------------| | | nohup отсутствуют командная_строка | | +-----------------------------------------------------------------------| | | Описание: Позволяет продолжать выполнение командной строки, | | | если даже разрывается связь с терминалом, или поль- | | | зователь выходит из системы. | | +-----------------------------------------------------------------------+ Теперь после усвоения основных команд shell'а можно приступить к их использованию в shell-программах. Упражнения, которые сле- дуют ниже, помогут приобрести навыки в работе с командным язы- ком shell. Ответы к упражнениям даются в конце главы. 5.2 УПРАЖНЕНИЯ НА ИСПОЛЬЗОВАНИЕ КОМАНДНОГО ЯЗЫКА 1-1. Что произойдет, если использовать звездочку * в начале имени файла? Попробуйте вывести список файлов каталога, указав звездочку * с последним символом имени одного из файлов. Что произойдет? 1-2. Выполните следующие две команды: |cat [0-9]* |echo * Каков будет результат? 1-3. Можно ли использовать знак ? в начале или середине имени файла при сопоставлении имен? Проверьте это. 1-4. Есть ли у Вас какие-либо файлы, имя которых начинается с цифры? Можно ли вывести список только этих файлов, не вы- водя другие файлы? Можно ли вывести список только тех файлов, имена которых начинаются со строчных букв в диа пазоне от a до m? (Подсказка: используйте диапазон цифр или букв в скобках [].) 1-5. Допускается ли указание команды запуска в фоновом режиме в строке, которая последовательно выполняет несколько ко- манд? Проверьте это. Что происходит? (Подсказка: исполь- зуйте знаки ; и &.) Может ли такая команда находиться в любом месте командной строки? Попробуйте устанавливать ее в различных позициях строки. 1-6. Переадресуйте вывод команд pwd и ls на файл proba, произ- ведя соответствующие изменения в следующей командной строке: |cd;pwd;ls;rk trial Помните, что для переадресации вывода обеих команд в один и тот же файл, для второй команды следует использовать знак >> (добавление). Если не сделать этого, будет унич- тожен результат работы команды pwd. 1-7. Вместо выделения времени в выводе команды date (как это показано в п. 5.1.3.8), попытайтесь вывести плакатными буквами с помощью команды banner только дату без указания времени. Какую часть командной строки в примере с выделе- нием времени следует изменить? |banner `date | cut -c12-19`