Давно не виделись. Давай сразу к делу. У меня есть скрипт с бесконечным циклом, который выполняет какие-то действия.
Задача: нужно, чтобы скрипт отработал 3 минуты и завершился.
Можно, конечно, запустить скрипт, подождать 3 минуты и руками его стопнуть через Ctrl+C, но это не трувей. А что, если нужно 5 минут или 45? Не буду же я сидеть всё это время в ожидании.
К счастью, у нас с тобой есть утилита timeout, которая уже идёт в коробке с Linux.
Вот с помощью этой утилиты можно ограничивать по времени выполнение скриптов и команд. Давай рассмотрим примеры.
timeout 3s ping www.bashdayz.ru
Команда ping отработает 3 секунды и завершится. Конечно, у ping есть свои ключи для этого, но сегодня у нас про другое.
Синтаксис у команды timeout довольно простой:
timeout DURATION COMMAND
DURATION = длительность. Это число с плавающей запятой и с необязательным суффиксом следующего вида:
- s = секунды;
- m = минуты;
- h = часы;
- d = дни.
COMMAND = сама команда или скрипт, которому нужно ограничить работу по времени.
Допустим, мне нужно запустить какое-то приложение (например, top) на удалённом сервере и через 3 минуты всё это безобразие прекратить. Ок, делаем такое:
timeout 3m ssh user@bashdayz.ru -- /usr/bin/top
Прошло 3 минуты, приложение гасится, SSH-сессия завершается. Удобно? Удобно!
Если по истечении этого времени у тебя в терминале исчез курсор (частенько такое бывает), то выполни команду reset, терминал сбросится и всё вернётся на круги своя.
Также можно послать определённый сигнал завершения для приложения. К примеру:
timeout -s 9 3m ping www.bashdayz.ru
Чтобы получить список всех сигналов, можешь выполнить команду kill -l и посмотреть. Их там достаточно много. Я не заморачиваюсь и рублю с плеча сигналом 9 (SIGKILL). Убивать так убивать.
Вместо номера сигнала можно указывать явное имя:
timeout -s SIGTERM 5m ping www.bashdayz.ru
У timeout есть ещё несколько опций, но я никогда не видел, чтобы кто-то их использовал, так что можно забить. Возможно, они пригодятся для каких-то специфичных задач, но я с такими, к счастью, не сталкивался.
Ладно. Утилита timeout — это клёво, а как реализовать то же самое, не применяя её, на чистом Bash? Смотри:
ping www.bashdayz.ru & read -t 3 || kill $!
В этом примере выполняется ping и по прошествии 3 секунд завершается. Тут уже тебе самому решать: использовать timeout либо подобную конструкцию.
А, точно, забыл объяснить про символ «$!». Эта конструкция содержит в себе идентификатор процесса (PID) последнего выполненного фонового конвейера. В примере выше последним выполненным заданием был ping. То есть явно не нужно указывать PID, чтобы kill корректно отработал.
Собственно, на этом всё. Век живи, век учись. Котиков тебе и удачи. Давай, увидимся!







