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


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


XTRA=no SORT=sort -b +2 DISPLAY=norm CUT1=cut -d' ' -f1 <- Одинарные кавычки все еще здесь. Основная проблема. CUT5=cut -d: -f5 CUT6=cut -d: -f6 XTRA=yes + who + read LINE + sort -b +2 + echo russ console Jun 20 14:11 + cut -d -f1 <- Теперь выполняется правильно. Кавычек нет.

Это сокращенная распечатка. Она показывает, что когда выполнялась команда cut, она не имела одинарных кавычек. Когда же запускалась переменная CUT1, она имела одинарные кавычки. Я не мог представить, как избавиться от кавычек, поэтому я просто вставил вызов самой команды cut обратно на это место. Может быть какой-нибудь молодой растущий мастер сможет себе это представить.

Во всяком случае, вы можете видеть полезность отладки.

Цикл, выполняющий такое же присваивание, имеет такой вид при обычном стиле записи на языке shell:

| while read LINE do NAME=`echo $LINE | cut -d' ' -f1` ENTRY=`grep "^$NAME:" /etc/passwd` echo "$LINE\t\`echo $ENTRY|$CUT6\`\t\`echo $ENTRY|$CUT5\`\" done

Для того чтобы поместить такой же цикл в переменную, мы должны экранировать в этом тексте все специальные символы.

Строки 45-60 - это оператор case, который реализует различные режимы отображения. Строка 46 выполняет обычный режим отображения команды who. Поскольку в обычном режиме имеется возможность использовать переменную EXTRA, нам необходимо произвести повторный разбор командной строки командой eval, чтобы эта переменная приняла свое истинное значение во время исполнения. Обратите внимание, что в команде eval имеются кавычки, заключающие всю командную строку. Это необходимо потому, что вся строка является одним набором входных данных для команды eval. Без кавычек команда eval не работала бы. Переменная EXTRA не подвергается повторному разбору.

Строки 47-50 управляют режимами указания пользователя и выдачи информации из файла паролей. Оба эти режима используют один и тот же цикл. Цикл for использован для установки переменной NAME в значение первого поля каждой строки, полученной от команды who. Для каждого имени, вырезанного из результата работы команды who, выполняется повторный синтаксический разбор командой eval переменной COMMAND (которая была установлена в операторе case, выполнявшем разбор аргументов). Тем самым повторно анализируются и выполняются команды, находящиеся в переменной COMMAND. Для режима указания пользователя переменная COMMAND содержит команду finger, а для режима паролей в COMMAND хранится команда grep.

Строки 51-58 похожи на режим указания пользователя. Этот цикл тоже требует имена от команды who, но вместо использования оператора for мы используем метод прямой пересылки по конвейеру. Результат работы команды who по конвейеру передается команде cut (переменная CUT1 и здесь бы не работала), которая по конвейеру передает данные в цикл чтения while. Обратите внимание, что в этом месте нет никакой сортировки. По умолчанию результат команды who выводится в порядке номеров терминальных устройств. Я не думаю, однако, что порядок вывода этих данных имеет большое значение.

Для каждого имени пользователя выводится запрос о том, хотите ли вы передать ему почтовое сообщение. При чтении ответа в строке 54 должна быть использована команда UNIX'а line. Почему? Потому что весь цикл использует оператор read для чтения имен. Оператор read читает только со стандартного ввода, который в данном случае привязан к конвейеру. Для получения входных данных с клавиатуры мы должны использовать команду line, которая получает их из файла /dev/tty. Это распространенный способ чтения данных с клавиатуры из переадресованного цикла.

Строка 55 проверяет, является ли ответом символ y. Если да, вызывается команда UNIX'а mail, и снова ввод переадресовывается из файла /dev/tty (поскольку строки почтового сообщения мы должны вводить с клавиатуры.) В данном случае мы фактически переадресовываем стандартный ввод для вызова подчиненного shell-процесса, выполняющего команду mail. Без выполнения переадресации команда mail читает из файла /dev/null, что нарушает выполнение всего цикла whox.

Строка 59 управляет режимом показа возможности записи на терминал. Цель здесь такова - использовать одну команду ls и, применяя подчиненный процесс, извлечь файлы терминальных устройств из выходных данных команды who. Эти файлы являются вторым полем результата команды who. Сначала запускается команда who, которая по конвейеру передает свои данные команде sed.

Затем sed использует команду подстановки для отбрасывания всего, кроме того, что ограничено символами \( и \). Последующая часть команды подстановки ссылается на этот ограниченный участок с помощью обозначения \1. Используя символ . как соответствующий любому символу распечатки, мы должны всего лишь посчитать столбцы, которые нам нужно вырезать. Кроме того, имена устройств в команде who не имеют префикса /dev/, который нам необходим. Команда sed вставляет его перед текстом, вырезанным из команды who. В результате команде ls дается список полных маршрутных имен ко всем файлам устройств зарегистрированных пользователей. Затем это выводится на экран.




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



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