Приемы профессиональной работы в UNIX


ОСВЕДОМЛЕННОСТЬ ПОЛЬЗОВАТЕЛЯ - часть 11


1. $ sh -x whox -x

Запуск интерпретатора shell в отладочном режиме выполнения, подача ему командного файла whox в качестве данных, передача опции -x для whox. Отладочный режим показывает присвоение значений переменным и вызовы команд. (Мы видели это ранее.) 2. $ whox -n -x

Печать выходных данных команды who, отсортированных по именам и выдача дополнительных данных.

ПОЯСНЕНИЯ

В строках 4-10 выполняется инициализация переменных. Переменная XTRA устанавливается в значение "no". Эта переменная используется для построения командной строки при использовании опции -x. Установка XTRA в значение "no" означает, что действие по умолчанию - не получать дополнительную информацию.

Умолчанием для сортировки является сортировка по времени регистрации. Это указывается сортировкой по колонке, стоящей после второй (+2) и игнорированием ведущих пробелов (-b) в строке 5. Такой же синтаксис применен ниже с опцией -t. Опция -t здесь лишняя, но она делает более понятной командную строку. Опция -n также изменяет синтаксис сортировки, чтобы просматривать первую колонку, которая является списком имен.

Строка 6 инициализирует обычный режим отображения, которым является печать стандартного выхода команды who. Если присутствуют другие опции, соответственно изменяется переменная DISPLAY.

Строки 8,9 и 10 инициализируют некоторые переменные для команд вырезки, что делает более компактными последующие команды. Если некоторые командные строки оказываются слишком длинными, вы можете поместить нужный текст в переменные и подставить их при необходимости. Переменная CUT1 выглядит так, как будто она должна работать, но она не работает в моей системе. Почему она не работает, объясняется ниже. Просто запомните, что эта строка никогда не используется в данной программе. Мы пока оставляем ее, чтобы поговорить о ней позже. Вы можете убрать ее, если хотите.

Строки 12-35 обрабатывают аргументы командной строки. Цикл for подставляет в переменную ARG каждый параметр по порядку и выполняет оператор case по значению ARG.

Если опцией является -f, строка 15 изменяет переменную DISPLAY в режим указания. Она также подставляет в переменную COMMAND команду finger, которая выполнится в следующем цикле. Причина, по которой нам нужно иметь переменную, содержащую команду, заключается в том, что данный цикл является общим циклом, применяемым для двух разных целей. Для того чтобы один и тот же цикл справился с двумя различными задачами, мы помещаем эти задачи в переменную и выполняем эту переменную.

Это значительно сокращает общее количество текста, хотя привносит некоторую дополнительную работу. Обратите внимание в строке 16, что символ $ экранирован в операторе присваивания. Это необходимо, ведь мы хотим, чтобы переменная COMMAND содержала символьную строку $NAME, а не значение, которое имеет переменная NAME после присваивания. Значение NAME расшифровывается в цикле во время его выполнения.

Строка 17 обрабатывает опцию -n. Все, что здесь требуется - изменить способ сортировки выхода команды who, чтобы отразить порядок по именам. Поскольку имя находится в первой колонке выхода команды who, а команда sort сортирует по умолчанию по первой колонке, то используется команда sort без опций.

Строка 18 обрабатывает опцию -m для передачи почтовых сообщений. Здесь мы должны изменить режим отображения на почтовый. Все, что нужно для этого, находится в цикле mail, и не требуется инициализировать никакие переменные.

Строки 19 и 20 справляются с опцией -p. Опция паролей изменяет режим отображения на парольный режим и устанавливает команду, которую мы вызываем, находясь в общем цикле. В данном случае мы используем команду grep для получения парольной записи из файла /etc/passwd. Обратите внимание, что в строке 20 мы используем внутренние двойные кавычки. Для этого мы вынуждены экранировать их символами обратной косой черты. Напомним, что обратная косая черта используется для отмены специального значения особых shell-символов.

Строка 21 управляет опцией -t. Как уже упоминалось ранее, опция -t в действительности не требуется в данной программе. Поскольку она является умолчанием, требуемые для нее действия уже были предприняты в начале программы - была выполнена точно такая же инициализация. Синтаксис команды sort точно такой же, как и в строке 5.

Строка 22 обрабатывает опцию -w для показа возможности записи в файлы терминалов. Единственное, что нужно здесь сделать - изменить режим работы терминала.

Строка 23 управляет опцией -x. Поскольку для получения дополнительной информации требуется довольно сложная инициализация, то мы только устанавливаем в этом месте флаг XTRA, показывающий, что мы хотим выполнить эту инициализацию позже.

Строка 24 - это улавливатель для обработки ошибок. Символ * соответствует любому символу, который не был распознан ранее. Печатается сообщение об ошибке и синтаксическая подсказка, и whox завершается.

Строки 37-43 устанавливают переменные, используемые в опции дополнительной информации. Строка 37 проверяет, установлена ли переменная XTRA в состояние "yes", что имеет место только тогда, когда в командной строке имелась опция -x. Если это так, то в переменную EXTRA заносится много всяких вещей, которые мы рассмотрим позже. В противном случае в переменную EXTRA заносится пустая строка, так что она никак не проявляется на стадии фактического выполнения.

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

Строки 38-41 вставлены внутрь переменной EXTRA. Это сделано путем взятия в двойные кавычки всех четырех строк. Все специальные символы, которые должны быть частью данных в этой переменной, должны быть экранированы символами обратной косой черты. В строке 38 в переменную EXTRA заносится символ конвейера (|) и начало цикла while. В конце строки 38 имеется символ косой черты, указывающий интерпретатору shell, что присваивание продолжается после символа конца строки (возврата каретки или перевода строки).

Строка 39 присваивает переменной NAME значение поля, вырезанного из данных, читаемых в цикле while. Напомним, что весь данный оператор помещается внутрь переменной EXTRA. Когда я выше упоминал, что в строке с переменной CUT1 есть проблемы, то как одно из таких проблемных мест я имел в виду именно это. Когда я попытался использовать переменную CUT1 в этом операторе вместо указания команды cut, shell не смог правильно распознать этот оператор. Одинарные кавычки, отмечающие символ-разделитель для вырезки, не были распознаны. В результате команда cut считала, что символом-разделителем является символ ' и после этого аварийно завершалась, поскольку второй символ ' представлял собой недопустимое описание списка для опции -f. Строка с опцией -f шла позже, но команда cut этого никогда не узнавала, поскольку аварийно завершалась до этого. Когда я заменил переменную CUT1 просто командой cut, эта проблема исчезла.

Давайте рассмотрим, как я отлаживал эту часть. Я использовал shell с опцией -x, поэтому я мог следить за тем, что происходит. Как вы можете видеть, когда переменная CUT1 была инициализирована, одинарные кавычки находились все еще в операторе, но когда выполнялась настоящая команда cut, одинарные кавычки уходили при синтаксическом расширении. Для генерации такого списка данных я выполнил следующий вызов: sh -x whox -x. Вот что я увидел:




Начало  Назад  Вперед



Книжный магазин