Этот ответ на команду командной строки для автоматического уничтожения команды через определенное время
предлагает 1-строчный метод для тайм-аута длительной команды из командной строки bash:
( /path/to/slow command with options ) & sleep 5 ; kill $!
Но возможно, что данная «длительная» команда может завершиться раньше, чем время ожидания. (Давайте назовем это «обычно продолжительной, но иногда быстрой» командой или tlrbsf для удовольствия.)
Так что у этого изящного подхода с 1 линией есть пара проблем. Во-первых, sleep
это не условно, так что устанавливает нежелательную нижнюю границу времени, необходимого для завершения последовательности. Рассмотрим 30 с, 2 м или даже 5 м для сна, когда команда tlrbsf заканчивается через 2 секунды, что крайне нежелательно. Во-вторых, kill
это безусловное условие, поэтому эта последовательность попытается убить не запущенный процесс и скулить по этому поводу.
Так...
Есть ли способ для тайм-аута обычно длительной, но иногда быстрой ( "tlrbsf" ) команды, которая
- имеет реализацию bash (на другой вопрос уже есть ответы на Perl и C)
- будет завершен в более раннем из двух: завершение программы tlrbsf или истекло время ожидания
- не будет уничтожать несуществующие / не запущенные процессы (или, опционально: не будет жаловаться на неудачное уничтожение)
- не должен быть 1-лайнер
- может работать под Cygwin или Linux
... и, для получения бонусных очков, запускает команду tlrbsf на переднем плане и любой «спящий» или дополнительный процесс в фоновом режиме, так что stdin / stdout / stderr команды tlrbsf может быть перенаправлен так же, как если бы он был бежать напрямую?
Если это так, пожалуйста, поделитесь своим кодом. Если нет, объясните, пожалуйста, почему.
Я потратил некоторое время, пытаясь взломать вышеупомянутый пример, но я достигаю предела своих навыков в bash.
источник
timeout
утилиту gnu ?timeout
отлично! Вы даже можете использовать несколько команд (многострочный скрипт): stackoverflow.com/a/61888916/658497Ответы:
Я думаю, что это именно то, что вы просите:
http://www.bashcookbook.com/bashinfo/source/bash-4.0/examples/scripts/timeout3
источник
Вы, вероятно, ищете
timeout
команду в coreutils. Поскольку это часть coreutils, технически это решение на C, но это все еще coreutils.info timeout
Больше подробностей. Вот пример:источник
gtimeout
brew install coreutils
, и тогда вы можете ее использоватьgtimeout
.Это решение работает независимо от режима мониторинга bash. Вы можете использовать правильный сигнал для завершения вашей_команды
Наблюдатель убивает your_command после заданного времени ожидания; скрипт ожидает медленной задачи и завершает работу наблюдателя. Обратите внимание, что
wait
не работает с процессами, которые являются потомками другой оболочки.Примеры:
источник
wait
возвращает состояние завершения процесса, которого он ожидает. Таким образом, если ваша команда завершает работу в течение выделенного времени, но с ненулевым состоянием выхода, тогда логика будет вести себя так, как истекло время ожидания, то есть печататьyour_command interrupted
. Вместо этого вы можете обойтисьwait
безif
и затем проверить, существует ли$watcher
pid, если он есть, то вы знаете, что время не истекло.kill
в одном случае, ноpkill
в другом. Мне нужно было использоватьpkill
оба, чтобы сделать это правильно. Я ожидаю, что если вы добавите команду()
, вам придется использовать ееpkill
для уничтожения. Но, возможно, это работает по-другому, если в. Есть только одна команда()
.Там вы идете:
Вы можете изменить
SIGINT
и10
по своему желанию;)источник
coreutils
пакете на FreeBSD.Вы можете сделать это полностью с
bash 4.3
и выше:_timeout 5 longrunning_command args
{ _timeout 5 producer || echo KABOOM $?; } | consumer
producer | { _timeout 5 consumer1; consumer2; }
Пример:
{ while date; do sleep .3; done; } | _timeout 5 cat | less
Нужен Bash 4.3 для
wait -n
Если вам не нужен код возврата, это можно сделать еще проще:
Ноты:
Строго говоря, вы не нуждаетесь в
;
in; )
, однако это делает вещь более последовательной для; }
-case. И,set +b
вероятно, тоже можно оставить, но лучше, чем потом сожалеть.За исключением
--forground
(возможно) вы можете реализовать все вариантыtimeout
поддержки.--preserve-status
это немного сложно, хотя. Это оставлено в качестве упражнения для читателя;)Этот рецепт может быть использован "естественно" в оболочке (так же естественно, как для
flock fd
):Однако, как объяснялось выше, вы не можете реэкспортировать переменные окружения в оболочку естественным образом.
Редактировать:
Пример из реальной жизни: Тайм-аут
__git_ps1
в случае, если он занимает слишком много времени (для таких вещей, как медленные SSHFS-ссылки):Edit2: исправление. Я заметил, что
exit 137
не нужен и делает_timeout
ненадежным одновременно.Edit3:
git
твердолобый, поэтому для удовлетворительной работы нужен двойной трюк.Edit4: забыл
_
в первом_timeout
для реального мира примере GIT.источник
cc. The 'wait' builtin has a new '-n' option to wait for the next child to change status.
От: tiswww.case.edu/php/chet/bash/NEWSЯ предпочитаю "timelimit", который имеет пакет, по крайней мере, в Debian.
http://devel.ringlet.net/sysutils/timelimit/
Это немного лучше, чем «таймаут» для coreutils, потому что он печатает что-то, когда убивает процесс, а также отправляет SIGKILL через некоторое время по умолчанию.
источник
timelimit -t1 ./a_forking_prog
убить только один из двух процессов), но timeout работает.Для тайм-аута
slowcommand
через 1 секунду:timeout 1 slowcommand || echo "I failed, perhaps due to time out"
Чтобы определить, истек ли срок действия команды или произошел сбой по ее собственным причинам, проверьте, имеет ли код состояния 124:
Обратите внимание, что когда состояние выхода равно 124, вы не знаете, истекло ли оно из-за вашей
timeout
команды или сама команда завершилась из-за какой-то внутренней логики тайм-аута, а затем вернула 124. Вы можете смело предполагать в любом случае Тем не менее, произошел какой-то тайм-аут.источник
Смотрите также http://www.pixelbeat.org/scripts/timeout скрипт, функциональность которого была интегрирована в более новые coreutils
источник
Вроде хак, но это работает. Не работает, если у вас есть другие процессы переднего плана (пожалуйста, помогите мне исправить это!)
На самом деле, я думаю, что вы можете отменить это, отвечая вашим «бонусным» критериям:
источник
Тайм-аут , вероятно, первый подход, чтобы попробовать. Вам может потребоваться уведомление или другая команда для выполнения, если она истекает. После долгих поисков и экспериментов я придумал сценарий bash :
источник
Простой скрипт с понятностью кода. Сохранить в
/usr/local/bin/run
:Тайм-аут команды, которая выполняется слишком долго:
Заканчивается сразу для команды, которая завершает:
источник
Если вы уже знаете имя программы (предположим
program
), что она завершается после истечения времени ожидания (в качестве примера,3
секунд), я могу предложить простое и несколько грязное альтернативное решение:Это прекрасно работает, если я вызываю тестовые процессы с помощью системных вызовов.
источник
argv[0]
, возможно, с другими хаки, чтобы освободить место).(sleep 3 && docker stop <container>) &
работало хорошо. Спасибо!{ sleep 5 && kill -9 $(ps -fe | grep "program" | grep $$ | tr -s " " | cut -d" " -f2); } & SLEEPPID=$!; bash -c "program" && kill -9 $SLEEPPID"
таким образом, он будет убивать только рабочие места в текущей оболочке.Есть также
cratimeout
Мартин Кракауэр (написан на C для систем Unix и Linux).источник
OS X пока не использует bash 4 и не имеет / usr / bin / timeout, так что вот функция, которая работает в OS X без home-brew или macports, которая похожа на / usr / bin / timeout (основана на Tino's ответ). Проверка параметров, помощь, использование и поддержка других сигналов - упражнение для читателя.
источник
В 99% случаев ответ НЕ для реализации какой-либо логики тайм-аута. Тайм - аут логика почти в любой ситуации красный предупреждающий знак , что что - то еще не так и должно быть исправлено вместо .
Ваш процесс иногда зависает или прерывается через n секунд? Затем выясните причину и исправьте это.
Кроме того, для правильного решения проблемы strager вам нужно использовать wait "$ SPID" вместо fg 1, так как в сценариях у вас нет управления заданиями (и пытаться включить его глупо). Более того, fg 1 основывается на том факте, что вы ранее не запускали никаких других заданий в сценарии, что является неверным предположением.
источник
Мне представили проблему с сохранением контекста оболочки и разрешением тайм-аутов, единственная проблема в том, что он остановит выполнение скрипта по тайм-ауту - но это соответствует потребностям, которые мне были представлены:
с выходами:
конечно, я предполагаю, что там был режиссер
scripts
источник
источник
Моя проблема была, возможно, немного другой: я запускаю команду через ssh на удаленной машине и хочу уничтожить оболочку и дочерние элементы, если команда зависает.
Теперь я использую следующее:
Таким образом, команда возвращает 255 при истечении времени ожидания или кода возврата команды в случае успеха
Обратите внимание, что процессы уничтожения в ssh-сессии обрабатываются не так, как в интерактивной оболочке. Но вы также можете использовать опцию -t для ssh для выделения псевдотерминала, поэтому он действует как интерактивная оболочка
источник
Вот версия, которая не основана на порождении дочернего процесса - мне нужен был автономный скрипт, который встраивал эту функцию. Это также делает интервал частичного опроса, так что вы можете опрашивать быстрее. тайм-аут был бы предпочтительным - но я застрял на старом сервере
источник
Очень упрощенный способ:
с помощью pkill (опция -f ) вы можете уничтожить вашу конкретную команду с аргументами или указать -n, чтобы избежать уничтожения старого процесса.
источник
Опираясь на ответ @ loup ...
Если вы хотите отключить процесс и отключить вывод kill / pid, выполните:
Это помещает фоновый процесс в подоболочку, поэтому вы не видите выходных данных задания.
источник
У меня есть работа cron, которая вызывает скрипт php, и иногда он застревает на скрипте php. Это решение было идеальным для меня.
Я использую:
источник
scripttimeout
?