Давно не виделись 🥳 Давай сразу к делу. У меня есть скрипт с бесконечным циклом, который выполняет какие-то действия.



Задача: нужно чтобы скрипт отработал 3 минуты и завершился.



Можно конечно запустить скрипт, подождать 3 минуты и руками его стопнуть через ctrl+c, но это не трувей. А что если нужно 5 минут или 45? Не буду же я сидеть всё это время в ожидании.



К счастью у нас с тобой есть утилита timeout, которая уже идет в коробке с Linux.



Timeout, это утилита командной строки, которая запускает указанную команду и завершает ее, если она все еще выполняется через определенный промежуток времени. Другими словами, timeout позволяет запустить команду с ограничением по времени. Команда timeout является частью пакета основных утилит GNU, который устанавливается практически в любом дистрибутиве 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 [email protected] -- /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 корректно отработал.



Собственно на этом всё. В Linux столько всего интересного, но не каждый про это интересное знает. Я изначально использовал bash конструкцию и только спустя какое-то время узнал про утилиту timeout. Век живи, век учись. 😐 Котиков тебе и удачи. Давай, увидимся!



tags: #bash #utils #linux



🟢 Подпишись: @bashdays