fi
for pid in $pids
do
··# Послать сигнал $signal процессу с идентификатором $pid: kill при этом
··#·· может вывести сообщение, если процесс уже завершился, если пользователь
··#·· не имеет прав завершить процесс и так далее, но это нормально. Свою
··#·· работу мы сделали.
··if [$donothing −eq 1]; then
····echo "kill $signal $pid" # Флаг −n: "показать и ничего больше не делать"
··else
····kill $signal $pid
··fi
done
exit 0
Как это работает
Так как этот сценарий выполняет агрессивную операцию и потенциально опасен, мы постарались минимизировать ложные совпадения с шаблоном, чтобы шаблон, например sh, не совпадал с такими строками в выводе ps, как bash или vi crashtest.c. Это достигается включением в шаблон префикса в команде awk (
Добавление ведущего пробела перед шаблоном $1 и завершающего якорного метасимвола $ заставляет сценарий выполнять поиск в выводе команды ps не по шаблону 'sh', а по шаблону ' sh$'.
Запуск сценария
Этот сценарий имеет несколько начальных флагов, позволяющих управлять его поведением. Флаг −s SIGNAL позволяет указать сигнал, который должен посылаться найденному процессу или процессам вместо сигнала по умолчанию SIGINT. Флаги −u USER и −t TTY удобны в первую очередь для пользователя root, поскольку дают ему возможность послать сигнал всем процессам, связанным с указанным пользователем или устройством TTY соответственно. А флаг −n позволяет заставить сценарий вывести список найденных процессов без отправки любых сигналов. Наконец, должен быть указан шаблон для поиска процессов.
Результаты
Теперь завершить все процессы csmount в OS X можно с помощью сценария killall, как показано в листинге 6.7.
Листинг 6.7. Завершение всех процессов csmount с помощью сценария killall
$./killall −n csmount
kill −INT 1292
kill −INT 1296
kill −INT 1306
kill −INT 1310
kill −INT 1318
Усовершенствование сценария
Иногда при работе сценария возникает маловероятная, но возможная ошибка. Чтобы обеспечить более полное совпадение с заданным шаблоном, команда awk выводит идентификаторы только для процессов, имена которых содержат шаблон в конце, плюс ведущий пробел. Но теоретически возможна ситуация, когда в системе имеется два процесса: один с именем bash и другой с именем emulate bash. Если вызвать сценарий killall с шаблоном bash, оба процесса совпадут с ним, хотя только первое совпадение будет истинным. Решить эту проблему и обеспечить непротиворечивые результаты во всех системах очень непросто.
Если вы заинтересованы в этом, напишите на основе killall свой сценарий, который позволял бы изменять приоритет процессов с помощью команды renice по их именам, а не по числовым идентификаторам. В этом случае потребуется только вызвать renice вместо kill. Команда renice изменяет относительные приоритеты выполняющихся программ, позволяя, к примеру, уменьшать приоритет процесса, занимающегося передачей большого файла, и увеличивать приоритет видеоредактора, которым в данный момент пользуется начальник.
№ 48. Проверка записей в пользовательских файлах crontab
Одним из самых удобных механизмов во вселенной Linux является планировщик cron, позволяющий планировать выполнение заданий в произвольные моменты времени в будущем или автоматически запускать их каждую минуту, каждые несколько часов, раз в месяц или даже раз в год. Каждый хороший системный администратор имеет свой комплект сценариев, запускаемых из файла crontab.
Однако формат определения заданий в cron довольно сложен: поля могут определяться как числа, диапазоны, множества и даже содержать мнемонические имена дней недели или месяцев. Хуже того, программа crontab выводит малопонятные сообщения об ошибках, когда встречает огрехи в системном или пользовательском файле с заданиями для планировщика cron.
Например, если допустить опечатку в названии дня недели, crontab выведет примерно такое сообщение об ошибке:
"/tmp/crontab.Dj7Tr4vw6R":9: bad day-of-week
crontab: errors in crontab file, can't install
Фактически в файле, вызывающем эту ошибку, есть вторая ошибка в строке 12, но crontab вынуждает нас пройти долгий путь, чтобы найти ее, из-за некачественной реализации кода, выполняющего проверку на наличие ошибок.