Жанр: Учеба
Приемы профессиональной работы в Unix
...ию и затем пятое
поле файла паролей. Мы получили это поле таким же образом, как и
шестое поле - эхо-отображением и выделением.
Такая техника получения данных медленная, поскольку вовлечены все
процессы, но это самый быстрый путь сделать это на языке shell. Команда
awk была бы понятнее и, возможно, быстрее, но наша реализация демонстрирует
гибкость языка shell. Язык shell может выполнять почти
все, но не всегда лучшим образом. Вот почему в некоторых случаях мы
используем язык Си, в чем вы убедитесь по мере продвижения по нашей
книге.
---------------------------------------------------------------------------
ИМЯ: uchk
---------------------------------------------------------------------------
uchk Проверка процессов, запущенных другим пользователем
НАЗНАЧЕНИЕ
Отобразить все процессы каждого пользователя, указанного в командной
строке
ФОРМАТ ВЫЗОВА
uchk [-a] login_name [...]
ПРИМЕР ВЫЗОВА
uchk -a Вывод всех процессов, запущенных администраторами
ТЕКСТ ПРОГРАММЫ
1 :
2 # @(#) uchk v1.0 Check processes of another user Author: Russ Sage
2а Проверка процессов другого пользователя
4 trap "rm /tmp/ps$$ 2" /dev/null" 0 1 2 3 15
6 if [ $# -eq 0 ]
7 then echo "uchk: argument error" "&2
8 echo "usage: uchk [-a] login_name [ ... ]" "&2
9 exit 1
10 fi
12 if [ "`echo $1 | cut -c1`" = "-" -a "$1" != "-a" ]
13 then echo "uchk: invalid argument $1" "&2
14 echo "usage: uchk [-a] login_name [ ... ]" "&2
15 exit 1
16 fi
18 ADMIN="administrators names go here"
19 if [ "$1" = "-a" ]
20 then shift
21 set $ADMIN $@
22 fi
24 ps -ef " /tmp/ps$$
25 for NAME
26 do
27 echo
28 fgrep "$NAME" /tmp/ps$$
29 done
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
ADMIN Строка с именами пользователей, являющихся
администраторами в вашей системе
NAME Содержит каждое имя, считываемое из командной строки
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ uchk?
Поскольку UNIX является многопользовательской системой, множество
задач выполняются одновременно. Единственный способ следить за такими
задачами - с помощью команды ps. Ps - это довольно специфичная команда
в том смысле, что она должна обращаться к памяти (/dev/mem) и проходить
по связанному списку структур процесса. Это тяжелая вещь, поэтому
нелегко сделать свою собственную команду для вывода такого рода информации.
Вдобавок память защищена, и доступ к ней имеет только пользователь
root.
Так что мы должны или удовлетвориться опциями, которые дает команда
ps, или модифицировать вывод этой команды. Uchk скорее относится
к последней категории. Мне хотелось получить список состояний процессов
по имени пользователя, а не смесь информации, относящейся к
разным пользователям. Хотя то, что я хотел, не соответствует ни одной
из стандартных опций команды ps, я смог модифицировать ее выход для
получения того, что мне надо.
ЧТО ДЕЛАЕТ uchk?
Uchk - это средство, которое генерирует, анализирует и сообщает о
процессах, запущенных каждым указанным пользователем. За один раз вы
можете проверить столько пользователей, сколько вам нужно. Все процессы
для каждого пользователя печатаются вместе.
Чтобы делать это, uchk должен работать с временными файлами.
Система UNIX весьма элегантно управляет временными файлами. Shell позволяет
использовать идентификатор процесса для создания уникальных
имен файлов для каждого запуска. После того как утилита запущена, временные
файлы очищаются путем использования команды trap в shell'е. Команда
trap удаляет файл, если что-либо прервало выполнение командного
файла или когда программа завершается. Это прекрасная особенность, которая
исключает накопление случайных файлов в системе.
Если uchk была вызвана без аргументов или была использована недопустимая
опция, то печатается сообщение об ошибке и выполнение завершается.
Uchk имеет переменную ADMIN, которая определяет всех администраторов
вашей системы. Отредактируйте символьную строку, присваиваемую
переменной ADMIN, указав имена администраторов, которых вы хотите проверить.
Имена должны быть разделены пробелами. Это позволит вам проверять
процессы ваших администраторов, указывая опцию -a в командной
строке. Все остальные имена должны быть указаны в командной строке.
Естественно, вы таким же образом могли бы установить другие группы
пользователей. Слежение за администраторами поможет вам оценить, как
они управляют сохранностью информации, а также распознать административные
задачи, которые имеют склонность загружать процессор.
ПРИМЕР
$ uchk -a russ uucp
Показывает процессы всех администраторов, мои собственные, и процессы
uucp по порядку. Все сообщения об ошибках выводятся на стандартное
устройство регистрации ошибок, а списки процессов выводятся на
стандартное устройство вывода.
ПОЯСНЕНИЯ
Строка 4 - это оператор trap. Символьная строка между двойными
кавычками содержит команды, которые должны быть выполнены, когда происходит
прерывание. В этом случае мы удаляем временный файл и переадресовываем
все выходные данные на нулевое устройство. Когда команда rm
пытается удалить несуществующий файл, выводятся сообщения об ошибках.
Поскольку мы не знаем, какие файлы могут быть в наличии в тот момент,
когда возникнет прерывание, то мы хотим избавиться от сообщений об
ошибках. Оператор trap активизируется по выходу из программы (program
exit, сигнал 0), разрыву линии (hangup, сигнал 1), прерыванию
(interrupt, сигнал 2), выходу (quit, сигнал 3) или программному завершению
(software termination, сигнал 15).
В строках 6-10 проверяется, переданы ли какие-либо аргументы.
Если вы вызвали uchk без аргументов, выводится сообщение об ошибке и
uchk завершается.
В строках 12-16 проверяется, указана ли какая-то опция со знаком
минус и является ли она опцией -a - единственно допустимой опцией. Командный
файл делает это, применяя команды проверки для сравнения двух
различных случаев. Первая проверка вырезает первый символ первого позиционного
параметра и смотрит, является ли он символом "-". Следующая
проверка делается для того, чтобы увидеть, что первый позиционный параметр
не является опцией -a. Поскольку обе проверки соединены операцией
AND, то для получения значения "истина" они обе должны быть
истинными. Если они обе истинны, выводится сообщение об ошибке и uchk
завершается.
Почему мы должны выполнять такую сложную проверку? Проблема в
том, что у нас нет иного способа определить, является первый позиционный
параметр опцией или нет. Он может быть опцией, а может быть именем,
которое нужно искать. Таким образом, мы должны задать вопрос:
"Является ли это опцией, и если да, то допустима ли эта опция?"
В строке 18 переменная ADMIN инициализируется символьной строкой,
следующей за ней. Это строка, которую вы должны модифицировать в соответствии
с вашей системой. Все, что вы должны сделать - это использовать
редактор vi и вставить в эту строку имена администраторов, разделенные
пробелами. Ниже мы используем переменную ADMIN для обработки
аргументов командной строки.
В строках 19-22 проверяется, была ли указана в командной строке
опция -a. Если да, эта опция удаляется из командной строки с целью избавления
от нее. Строка 21 использует команду set для того, чтобы поместить
символьную строку ADMIN в позиционные параметры. Команда set
вставляет значение переменной ADMIN, начиная с первого позиционного
параметра, и сдвигает все настоящие параметры вправо. Тем самым в цикл
for передается множество имен, которые должны быть обработаны.
В строке 24 выполняется команда ps для всех пользователей. Эта
команда использует опцию f для вывода большого количества данных. Результат
помещается во временный файл, в имени которого применяется
идентификационный номер процесса. Этот один большой файл представляет
собой источник для остальных распечаток. Возможно, все это немного
отстает от реального времени, но программа выполняется гораздо быстрее,
чем при многократном вызове команды ps.
Строки 25-29 представляют собой цикл for, который выполняется от
$1 до $x, где x - последний позиционный параметр. Для каждого имени
выполняется следующее: печатается пустая строка для разделения листинга
(строка 27), затем командой fgreps (для ускорения) выбираются из
временного файла все процессы, принадлежащие данному пользователю.
Благодаря применению команды fgrep для каждого имени пользователя, все
процессы данного пользователя печатаются за один раз. Когда закончится
проверка всех имен, указанных в командной строке, цикл завершится, завершится
командный файл и сработает оператор trap, который удаляет временный
файл.
---------------------------------------------------------------------------
ИМЯ: watch
---------------------------------------------------------------------------
watch Наблюдение за регистрацией указанных пользователей
НАЗНАЧЕНИЕ
Следит за тем, кто работает в системе, и сообщает
о регистрации указанных пользователей.
ФОРМАТ ВЫЗОВА
watch [-k] [login_name ...]
ПРИМЕР ВЫЗОВА
watch Наблюдение за регистрацией всех пользователей,
указанных во внутренней переменной LIST
ТЕКСТ ПРОГРАММЫ
1 :
2 # @(#) watch v1.0 Watch for specific logins Author: Russ Sage
2а Наблюдение за регистрацией пользователей
4 if [ "`echo $1 | cut -c1`" = "=" -a "$1" != "-k" ]
5 then echo "watch: invalid argument $1" "&2
6 echo "usage: watch [-k] [login_name ...]" "&2
7 echo " -k kill background process"
8 exit 1
9 fi
11 if [ "$1" = "-k" ]
12 then if [ -s $HOME/.watch ]
13 then echo "killed `cat $HOME/.watch`"
14 kill `cat $HOME/.watch`
15 rm $HOME/.watch
16 exit 0
17 fi
18 fi
20 echo $$ " $HOME/.watch
22 LIST="root sys bin administrator1 administrator2 $*"
24 while :
25 do
26 for NAME in `who | cut -d" " -f1`
27 do
28 for PERSON in $LIST
29 do
30 if [ "$NAME" = $PERSON" ]
31 then echo ONLINE: $NAME
32 fi
33 done
34 done
35 sleep 10
36 done &
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
HOME Полный маршрут к вашему регистрационному каталогу
LIST Список имен пользователей системы, разделенных
пробелами
NAME Содержит имена зарегистрированных в настоящий
момент пользователей
PERSON Отдельное имя из списка имен в переменной LIST
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ watch?
В течение рабочего дня множество людей входят в систему и выходят
из нее. Иногда единственный способ связаться с человеком - через машину.
Нам нужно средство, которое автоматически сообщит нам, что нужное
лицо на связи.
ЧТО ДЕЛАЕТ watch?
Подразумевается, что watch является фоновой задачей, которая
постоянно следит за тем, кто зарегистрировался. Когда лицо или лица,
предварительно вами отмеченные, регистрируются в системе, на ваш экран
выводится сообщение о том, что они на связи.
Количество имен, за которыми вы можете следить, не ограничено.
Общий перечень имен - это объединение имен, указанных в командной
строке, и списка системных пользователей, т.е. пользователя root и
всех сопровождающих его администраторов. В командном файле watch
список системных имен ВСЕГДА включен. Это вызвано тем, что это важные
пользователи и вы хотите всегда знать об их входе в систему и выходе
из нее. Это отличает watch от uchk, поскольку последний требует указания
опции -a для включения списка с системными именами.
Хотя мы устанавливаем watch с точки зрения пользователя, который
желает следить за администраторами и другими пользователями, администраторы
тоже могут иметь список "критических пользователей" или предполагаемых
нарушителей защиты информации и использовать watch для получения
сигнала о регистрации таких пользователей.
За кем бы мы ни следили, мы сталкиваемся с одной проблемой. После
регистрации в системе указанного лица сообщение об этом поступает на
ваш экран, не обращая внимания на то, чем вы в данное время занимались,
что не очень приятно. Единственный способ остановить вывод сообщения
- аварийно завершить watch командой kill. Это легко сделать путем
помещения идентификатора этого процесса в файл $HOME/.watch. Затем
этот номер может быть использован в операторе kill для остановки выполнения
командного файла. Для того чтобы попроще избавиться от watch,
возможность аварийного завершения оформлена в виде опции -k данного
командного файла.
ПРИМЕРЫ
1. $ LIST="root bin" watch daemon
Если переменная LIST не была инициализирована внутри самого командного
файла watch, то мы можем инициализировать ее на командном
уровне shell'а, а затем вызвать watch. Список пользователей для watch
будет такой: root, bin и daemon по порядку, поскольку watch добавляет
имена, указанные в ее командной строке к именам, имеющимся в переменной
LIST. Такой способ указания имен более гибок, чем жесткое программирование
части списка в тексте командного файла watch, но он требует
помнить больше информации и больше нужно набирать на клавиатуре.
2. echo "Watch (y/n): \c"
read ANS
if [ "$ANS" = "y" ]
then watch
fi
Это фрагмент, который вы можете вставить в ваш .profile. Когда вы
регистрируетесь, вам автоматически предлагается запустить watch. Если
вы ответите "y", watch станет фоновой задачей и запустится по умолчанию
(просматривая пользователей согласно списку в переменной LIST).
Если будет введен любой символ, отличный от y, watch не запустится.
ПОЯСНЕНИЯ
Строки 4-9 выполняют проверку на наличие ошибок в опциях командной
строки. Для первого позиционного параметра проверяется, что он
имеет тире и не является единственной допустимой опцией "-k". Если результатом
проверки является истина, печатается сообщение об ошибке и
командный файл завершается.
Строки 11-16 проверяют, что первый позиционный параметр - это -k.
Если это так, значит пользователь хочет уничтожить уже запущенный процесс
watch. В этом случае выводится сообщение, указывающее идентификатор
процесса, который будет уничтожен, и выполнение продолжается. В
строке 12 мы смотрим, существует ли в нашем регистрационном каталоге
файл с именем .watch. Если нет, то это означает, что предыдущий экземпляр
watch предположительно уже уничтожен и нет необходимости пытаться
сделать это снова, поэтому происходит переход к оставшейся
части программы и выполнение watch происходит так, как будто опция
"-k" не была указана.
Если же файл .watch имеется, то в строке 14 используется команда
kill для уничтожения фонового процесса watch. Напомним, что при
использовании опции -k мы подразумеваем, что watch был вызван ранее,
поэтому файл $HOME/.watch имеет идентификационный номер самого процесса
watch. В строке 15 удаляется временный файл watch и в строке 16
происходит выход из программы. Теперь командный файл watch более не
выполняется как фоновый.
Строка 20 выполняется, если опция -k не была указана или если нет
файла .watch. (Последнее может произойти, если пользователь пытается
уничтожить процесс, забыв, что он уже был уничтожен.) Если опция -k не
была указана, мы можем считать, что watch был вызван, чтобы стать фоновым
процессом и выполнять свою работу. Для того чтобы сделать это,
текущий процесс отображает свой идентификатор процесса в файл .watch.
Этот файл остается в вашем регистрационном каталоге до тех пор, пока
он не будет удален вручную или же изменен путем повторного запуска
watch.
В строке 22 инициализируется переменная LIST. Ее значением является
символьная строка с именами, разделенными пробелами. Вам нужно
вручную отредактировать переменную LIST перед запуском в вашей системе.
Просто уберите ее нынешнее содержимое и вставьте туда имена администраторов
вашей системы. Если в командной строке будут указаны дополнительные
имена пользователей, они будут добавлены в переменную
LIST посредством символов расширения параметров $*. Тем самым переменная
LIST станет основным списком всех имен пользователей, за которыми
будет вестись наблюдение.
Строки 24-36 выполняют цикл постоянного наблюдения. В начале каждой
итерации с помощью команды who создается список имен пользователей,
который передается циклу for в строке 26. Цикл for использует командную
подстановку для получения списка слов, образованного из первого
поля команды who. Каждое зарегистрированное имя сравнивается со
списком предварительно определенных имен, за которыми мы наблюдаем.
Обратите внимание, что внешний цикл while сам себя помещает на выполнение
в фоновом режиме. Это означает, что вам нет необходимости вводить
это с клавиатуры.
Строки 29-33 управляют внутренним циклом, который проходит по
именам, содержащимся в нашем основном списке, и сравнивает их с именами,
полученными от команды who. Когда имя, полученное от команды who
(имя зарегистрированного пользователя) совпадает с именем в нашем
списке, на экран выводится сообщение о том, что данное лицо зарегистрировалось.
После того как все имена проверены, командный файл watch приостанавливается
на 10 секунд (строка 35). Когда он снова пробуждается, выполняется
следующая итерация вечного цикла while. Все зарегистрированные
имена вновь сравниваются со списком. Это будет продолжаться до тех
пор, пока вы не прекратите выполнение watch. Как отмечалось ранее,
watch можно легко уничтожить с помощью опции -k или же вручную путем
ввода команды "kill `cat $HOME/.watch`".
МОДИФИКАЦИИ
Watch выполняет довольно мало работы и использует какую-то часть
времени центрального процессора. Вы можете поэкспериментировать с увеличением
интервала паузы (sleep), чтобы watch запускался не так часто.
Большинство пользователей находятся в системе по крайней мере минуту,
поэтому вы можете попробовать значение sleep(60). Вы по-прежнему можете
обнаружить регистрацию всех интересующих вас пользователей?
---------------------------------------------------------------------------
ИМЯ: whox
---------------------------------------------------------------------------
whox Команда who с дополнительными возможностями
НАЗНАЧЕНИЕ
Предоставляет много дополнений к выходу команды who и позволяет
применять данные who для других приложений.
ФОРМАТ ВЫЗОВА
whox [-f] [-n] [-m] [-p] [-t] [-w] [-x]
где
-f указывает каждого зарегистрированного пользователя
-n сортирует выход команды who по именам
-m передает почту каждому пользователю
-p выводит информацию о паролях пользователей
-t сортирует выход команды who по времени (умолчание)
-w показывает возможность записи на зарегистрированные
терминальные устройства
-x дополнительная информация о регистрационном
каталоге и паролях
ПРИМЕР ВЫЗОВА
whox -w
Показывает права доступа к файлу (возможность чтения и записи)
для каждого зарегистрированного терминального устройства
ТЕКСТ ПРОГРАММЫ
1 :
2 # @(#) whox v1.0 Who with expanded options Author: Russ Sage
2а Команда who с дополнительными опциями
4 XTRA="no"
5 SORT="sort -b +2"
6 DISPLAY="norm"
8 CUT1="cut -d' ' -f1"
9 CUT5="cut -d: -f5"
10 CUT6="cut -d: -f6"
12 for ARG in $@
13 do
14 case $ARG in
15 -f) DISPLAY="finger"
16 COMMAND="finger \$NAME; echo";;
17 -n) SORT="sort";;
18 -m) DISPLAY="mail";;
19 -p) DISPLAY="pass"
20 COMMAND="grep \"^\$NAME:\" /etc/passwd";;
21 -t) SORT="sort -b +2";;
22 -w) DISPLAY="write";;
23 -x) XTRA="yes";;
24 *) echo "whox: invalid option $ARG"
25 echo "usage: whox [-f] [-n] [-m] [-p] [-t] [-w] [-x]"
26 echo " -f finger users"
27 echo " -n sort by name"
28 echo " -m mail to each user"
29 echo " -p password info on users"
30 echo " -t sort by time (default)"
31 echo " -w show writeability of devices"
32 echo " -x extra home dir and gcos info"
33 exit 1;;
34 esac
35 done
37 if [ "$XTRA" = "yes" ]
38 then EXTRA="| while read LINE; do \
39 NAME=\`echo \$LINE | cut -d' ' -f1\`;\
40 ENTRY=\`grep \"^\$NAME:\" /etc/passwd\`;\
41 echo \"\$LINE\t\`echo \$ENTRY|\$CUT6\`\t\`echo \$ENTRY|\$CUT5\`
\";done"
42 else EXTRA=""
43 fi
45 case $DISPLAY in
46 norm) eval "who | $SORT $EXTRA";;
47 finger|pass) for NAME in `who | $SORT | cut -d' ' -f1`
48 do
49 eval $COMMAND
50 done;;
51 mail) who | cut -d' ' -f1 | while read NAME
52 do
53 echo "mail to $NAME (y/n): \c"
54 KB=`line " /dev/tty`
55 if [ "$KB" = "y" ]
56 then mail $NAME " /dev/tty
57 fi
58 done;;
59 write) ls -il `who | sed "s/...........\(.......\).*
/\/dev\/\1/"`;;
60 esac
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
ARG Аргументы командной строки
COMMAND Команда, которую следует выполнить при использовании
команды who со списком имен
CUT1 Содержит синтаксис для выделения первого поля строки
CUT5 Содержит синтаксис для выделения пятого поля строки
CUT6 Содержит синтаксис для выделения шестого поля строки
DISPLAY Определяет, какой режим отображения использовать
ENTRY Запись в файле паролей для указанного пользователя
EXTRA Данная переменная содержит полный цикл shell-команд,
хранимых в виде одной строки
KB Входные данные от клавиатуры, полученные в цикле
NAME Содержит в каждый данный момент времени одно имя из
списка всех регистрационных имен
SORT Содержит выполняемый тип сортировки
XTRA Флаг, определяющий, должны ли быть активизированы
дополнительные опции
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ whox?
Как уже ранее обсуждалось в других местах этой книги, система
UNIX стремится обеспечить минимум возможностей в любой заданной области
интересов. Это не значит, что UNIX плохая система. Наоборот, она
делает гораздо больше, чем большинство других операционных систем. Но
очень часто мы хотим сделать немного больше того, что нам предоставляет
базовая система.
Получение информации о том, кто использует машину, может быть
применено для многих целей. Основная информация предоставляется командой
who, но она может быть не в том виде, который вам нужен для конкретной
цели. В любом случае, все, что делает команда who - дает вам
моментальную информацию о том, кто зарегистрировался. Нам необходим
некоторый способ автоматического доступа к этому списку зарегистрированных
имен и использования его для наблюдения, общения или других целей.
ЧТО ДЕЛАЕТ whox?
Whox - это инструментальное средство, расширяющее возможности команды
who. Оно не только может переупорядочить в соответствии с вашими
требованиями список, полученный от команды who, но также может указать
каждого зарегистрированного пользователя, передать почтовое сообщение
любому зарегистрированному пользователю, просмотреть парольную информацию
всех зарегистрированных пользователей и показать информацию,
взятую из индексного дескриптора файла, соответствующего терминальному
устройству каждого зарегистрированного пользователя.
По умолчанию действие whox заключается в печати обычного выхода
команды who в порядке времени регистрации от более раннего до более
позднего. Опция -x добавляет к этому списку информацию из регистрационного
каталога и поле комментария из файла паролей. Если эта опция -x
кажется вам знакомой, то так оно и есть, поскольку это то же самое,
что и команда info, представленная ранее.
Whox имеет четыре различных режима отображения. Первый это формат
обычного выхода команды who. Whox позволяет вам сортировать его двумя
разными способами. Опция -n сортирует по именам, а опция -t (которую
не нужно указывать, поскольку она используется по умолчанию) сортирует
по времени регистрации.
Второй режим отображения состоит из режимов указания и паролей,
включаемых опциями -f и -p. Основное отличие от первого режима заключается
в том, что выход команды who не печатается, а используется для
генерации списка имен пользователей, который применяется для других
целей. Мы указываем каждого пользователя или печатаем парольную запись
каждого пользователя. Выполняемая команда хранится в переменной, поэтому
мы можем иметь общий цикл, использующий особым образом переменные.
(Команда finger имеется в системе Berkeley UNIX и в некоторых
других, но не во всех реализациях. Посмотрите руководство, чтобы выяснить,
что выводится на экран по этой команде.)
Третий режим - это почтовый режим, в котором вы имеете возможность
посылки почтового сообщения каждому зарегистрированному пользователю.
Вам задается вопрос о том, действительно ли вы хотите сделать
это. Больше от вас ничего не требуется. Этот режим выбирает опция -m.
Последний режим - это режим записи на терминал. Режим записи (опция
-w) показывает информацию о файле терминала для каждого зарегистрированного
терминального устройства. Эта информация полезна, если вы
х
...Поділитися у соцмережах