← Весь справочник

timeout и sleep

Ограничить время работы команды (timeout -s -k, код 124) и сделать паузу (sleep с единицами s, m, h, d)

timeout запускает команду и, если та не закончилась за отведённое время, посылает ей сигнал (по умолчанию SIGTERM). Нужен, чтобы зависший curl, проверка или скрипт не висели вечно — в cron, CI, циклах ожидания. sleep просто ждёт указанное время; вместе они дают классический цикл «проверять раз в секунду, но не дольше минуты».

Синтаксис

timeout [опции] длительность команда [аргументы…]
sleep число[единица]…

Длительность

ЗаписьЗначение
5 или 5s5 секунд (секунды — по умолчанию)
0.5полсекунды — дробные числа допустимы
2m / 1h / 1dминуты / часы / сутки
sleep 1m 30sу sleep несколько аргументов складываются: 90 секунд
sleep infinityждать бесконечно (удобно, чтобы контейнер не завершался)
timeout 0 …ограничение отключено

Опции timeout

ОпцияЧто делает
-s сигналкакой сигнал послать по истечении времени: TERM (по умолчанию), INT, HUP, KILL или номер
-k времяесли через это время после первого сигнала команда ещё жива — послать SIGKILL
--preserve-statusвернуть код самой команды (например, 143 = убита SIGTERM), а не 124
--foregroundне уводить команду в фон: она может читать с терминала и получать Ctrl+C; дочерние процессы при этом по таймауту не убиваются
-vсообщить в stderr, какой сигнал был послан

Коды возврата timeout

КодКогда
код командыкоманда успела завершиться сама
124время вышло и команде послан сигнал (кроме KILL)
125ошибка самого timeout (неверная опция или длительность)
126команда найдена, но не запускается (нет прав x)
127команда не найдена
137команда убита SIGKILL (-s KILL или сработал -k): 128 + 9

Примеры

# не ждать ответа сервера больше 5 секунд
timeout 5 curl -s http://localhost:8080/health

# отличить «не успел» от «упал»
timeout 10 ./check.sh
rc=$?
if [ "$rc" -eq 124 ]; then echo "превышено время"; elif [ "$rc" -ne 0 ]; then echo "ошибка $rc"; fi

# вежливо попросить завершиться, через 5 секунд — убить
timeout -k 5 30 ./long-job.sh

# послать Ctrl+C-сигнал вместо TERM (программа успеет сохранить состояние)
timeout -s INT 60 ./collector

# ждать, пока порт откроется, но не дольше 30 секунд
timeout 30 bash -c 'until ss -ltn | grep -q ":8080 "; do sleep 1; done'

# то же для файла
timeout 10 bash -c 'while [ ! -f /tmp/ready ]; do sleep 0.5; done' || echo "не дождались"

# паузы
sleep 2
sleep 0.2
sleep 1m 30s
sleep infinity &

# собрать данные ровно за 3 секунды
timeout 3 tail -f /var/log/syslog > sample.log

Подводные камни

  • Код 124 — это не ошибка команды. В set -e-скриптах и проверках CI timeout по истечении времени даёт ненулевой код 124 даже для «нормального» tail -f. Обрабатывай его явно: timeout 3 tail -f log || [ $? -eq 124 ].
  • Функции, алиасы и встроенные команды не работают. timeout 5 cd /tmp или timeout 5 моя_функция — «failed to run command», код 127: timeout запускает только программы. Оборачивай в bash -c '…'.
  • Сигнал можно проигнорировать. Если команда перехватывает или игнорирует SIGTERM, она отработает до конца, а timeout всё равно вернёт 124. Защита — -k 5 (добавочный SIGKILL) или -s KILL.
  • С -s KILL и -k код — 137, а не 124. Проверяй оба значения.
  • timeout уводит команду в фоновую группу процессов. Интерактивные программы (запрос пароля, read с терминала) не смогут читать ввод и Ctrl+C не дойдёт до них. Для них — --foreground.
  • Внутри конвейера ограничен только один элемент. cat big | timeout 1 head … ограничит head; cat получит SIGPIPE (код 141) после его завершения. Чтобы ограничить весь конвейер — timeout 1 bash -c 'a | b'.
  • sleep 1x и sleep -1 — ошибка с кодом 1, а не пауза. Единицы — только s, m, h, d.
  • Цикл while sleep 1 без timeout или счётчика может ждать вечно, если условие так и не выполнится.

См. также

background · kill · exit-codes · conditions-loops · curl · date