··askvalue month $nmon 12 2
··askvalue day $nday 31 2
··askvalue hour $nhr 24 2
··askvalue minute $nmin 59 2
··squished="$year$month$day$hour$minute"
··# Или, если сценарий предполагается использовать в Linux:
··# Да, в системах Linux и OS X/BSD используются разные форматы.
··# Так лучше?
··echo "Setting date to $squished. You might need to enter your sudo password: "
··sudo date $squished
··exit 0
Как это работает
Чтобы максимально уменьшить размер сценария, мы использовали функцию eval
Нам также нужно гарантировать использование строки с датой правильного формата, потому что, например, в OS X и в Linux он различается. По умолчанию данный сценарий использует формат даты, принятый в OS X, но в строке с комментарием
Вот одна из малозаметных проблем, возникающих при работе с командой date. Если в ответ на запросы сценария ввести точное время, а затем потратить несколько мгновений на ввод пароля для sudo, системное время будет на пару секунд отставать от текущего. Возможно, это совсем не проблема, но одна из причин, почему системы, подключенные к сети, должны использовать утилиты NTP (Network Time Protocol — сетевой протокол службы времени) для синхронизации с официальным сервером времени. Знакомство с механизмом синхронизации времени по сети в системах Linux и Unix можно начать с чтения страницы справочного руководства timed(8).
Запуск сценария
Обратите внимание, что сценарий использует команду sudo для вызова команды date с привилегиями root, что наглядно демонстрирует листинг 6.5. Вводя неправильный пароль в ответ на запросы sudo, вы можете экспериментировать со сценарием, не боясь получить неожиданные результаты.
Результаты
Листинг 6.5. Тестирование интерактивного сценария setdate
$ setdate
year [2017]:
month [05]:
day [07]:
hour [16]: 14
minute [53]: 50
Setting date to 201705071450. You might need to enter your sudo password:
passwd:
$
№ 47. Завершение процессов по имени
В Linux и в отдельных версиях Unix имеется удобная команда killall, позволяющая завершать все работающие приложения, имена которых соответствуют заданному шаблону. Это может пригодиться, например, для завершения всех девяти демонов mingetty или даже просто для отправки сигнала SIGHUP демону xinetd, чтобы заставить его перечитать файл конфигурации. В системах, не имеющих команды killall, можно эмулировать ее с помощью сценария командной оболочки, использующего команду ps для идентификации процессов и их завершения отправкой заданного сигнала.
Самую большую сложность в этом сценарии представляют различия в выводе команды ps в разных операционных системах. Например, давайте посмотрим, насколько различаются выводы по умолчанию команды ps в FreeBSD, Red Hat Linux и OS X.
Сначала посмотрим, что выводится в FreeBSD:
BSD $ ps
PID TT··STAT····TIME COMMAND
792··0··Ss·· 0:00.02 −sh (sh)
4468··0··R+·· 0:00.01 ps
Сравните с выводом в Red Hat Linux:
RHL $ ps
··PID TTY········ TIME CMD
8065 pts/4·· 00:00:00 bash
12619 pts/4·· 00:00:00 ps
И, наконец, с выводом в OS X:
OSX $ ps
··PID TTY··········TIME CMD
37055 ttys000·· 0:00.01 −bash
26881 ttys001·· 0:00.08 −bash
Что еще хуже, вместо того чтобы смоделировать типичную Unix-команду ps, GNU-версия команды ps принимает флаги в стиле BSD, в стиле SYSV