Как ограничить время команды через GNU timeout в Linux

Как ограничить время команды через GNU timeout в Linux
Содержание статьи

Учебная команда должна завершаться за ограниченное время, но иногда остаётся ждать бесконечно. В GNU/Linux для такого запуска подходит timeout из GNU Coreutils. В практикуме Mentoring.digital ограничим обычный sleep и отдельно прочитаем результат.

Задайте срок и сохраните код сразу

Это примеры для оболочки sh или Bash и реализации GNU timeout. В Windows есть одноимённая команда с другим назначением. Сначала проверьте доступную реализацию через timeout --version, затем выполняйте учебные команды в своей тестовой оболочке.

if timeout 2s sleep 5; then
    status=0
else
    status=$?
fi
printf 'exit=%s\n' "$status"

При обычном срабатывании лимита ожидается exit=124. По умолчанию timeout посылает TERM. Конструкция if позволяет сохранить неуспешный статус, в том числе в сценарии со строгой обработкой ошибок. Если сначала выполнить другую команду, значение $? уже будет относиться к ней.

Когда команда завершилась сама до лимита, возвращается её код. Поэтому ненулевое значение не всегда означает тайм-аут. GNU timeout также использует 125 при собственной ошибке, 126 когда найденную команду нельзя запустить и 127 когда она не найдена. Команда сама тоже может вернуть совпадающее число: учитывайте контекст и журнал.

TERM даёт возможность завершиться, KILL задаёт предел ожидания

Процесс может обработать или проигнорировать TERM. Дополнительный срок --kill-after отсчитывается от отправки первого сигнала, а не от старта. Следующий учебный процесс игнорирует TERM, поэтому после первоначальных двух секунд даётся ещё одна секунда до KILL:

if timeout --kill-after=1s 2s sh -c 'trap "" TERM; sleep 10'; then
    status=0
else
    status=$?
fi
printf 'exit=%s\n' "$status"

Для такого принудительного завершения ожидается 137. Фактический момент зависит от планирования системы: это не точный секундомер. Код 137 может означать KILL как для контролируемого процесса, так и для самого timeout; по одному числу эти варианты не различить.

Остановка не отменяет сделанную работу

Если команда до остановки успела отправить запрос или записать данные, timeout не откатывает эти действия. После превышения срока сначала выясняют фактический результат операции, а уже потом решают, допустим ли повтор. Особенно это важно для неидемпотентных действий.

Параметр --foreground нужен для определённых сценариев взаимодействия с терминалом, но меняет охват: дочерние процессы команды в этом режиме не ограничиваются тайм-аутом. Не считайте timeout гарантией остановки любого дерева процессов. Значение длительности 0 отключает соответствующий лимит.

Проверьте три исхода на учебных командах

Сравните быстрый успешный запуск, обычное превышение срока и принудительное завершение после игнорирования TERM. Сохраняйте команду, stderr и код, не подменяя ими подтверждение результата внешней операции. Для рабочего сервиса порядок остановки и восстановления требуется проектировать отдельно.

Основы процессов и оболочки можно разобрать на обучении DevOps. Если ограничение времени нужно для вашей задачи CI, подготовьте обезличенный сценарий для наставника по DevOps.

Похожие статьи по данной теме