Автоматически уничтожьте процесс, если его время выполнения превышает некоторое предопределенное значение

С точки зрения безопасности ответ - то, что в текущих дистрибутивах Вы не можете сказать, какое приложение это. См. этот отчет об ошибках для разъяснения от разработчика брелока для ключей гнома, включая последствия безопасности и объем задачи.

С практической точки зрения я также использую автовход в систему на Ubuntu, и кажется, что это - действительно nm-апплет.

5
18.04.2018, 13:39
3 ответа

Bash запись FAQ № 68: "Как я выполняю команду и имею ее аварийное прекращение работы (тайм-аут) после N секунды?"

СНАЧАЛА проверьте, может ли команда, которую Вы выполняете, быть сказана тайм-ауту непосредственно. Методы, описанные здесь, являются "hacky" обходными решениями, чтобы вынудить команду завершиться после того, как определенное время протекло. Конфигурирование Вашей команды правильно всегда предпочтительно для альтернатив ниже.

Если команда не имеет никакой собственной поддержки остановки после требуемого времени, то лучшие альтернативы являются некоторыми внешними командами, названными тайм-аутом и doalarm. Некоторые дистрибутивы Linux предлагают tct версию тайм-аута как пакет. Существует также версия GNU тайм-аута, включенного в недавние выпуски coreutils.

Остерегайтесь: по умолчанию некоторые реализации тайм-аута выходят, SIGKILL (уничтожьте-9), который является примерно тем же как вытаскиванием шнура питания (оставляющий шанс для программы для фиксации ее работы, часто приводящей к повреждению ее данных). Необходимо использовать сигнал, который позволяет программе завершать работу себя вместо этого (SIGTERM). Посмотрите ProcessManagement для получения дополнительной информации о SIGKILL.

Главная разница между doalarm и тайм-аутом - то, что doalarm "должностные лица" программа после установки предупреждения, которое делает это замечательным в WrapperScript; в то время как тайм-аут запускает программу как ребенка и затем бродит вокруг (оба процесса существуют одновременно), который дает ему возможность отправить больше, чем сигнал единицы при необходимости.

Если Вы не имеете или не хотите одну из вышеупомянутых программ, можно использовать остроту жемчуга для установки ALRM и затем должностного лица программа, которую Вы хотите запустить под ограничением по времени. В любом случае необходимо понять то, что программа делает с SIGALRM; программы с периодическими обновлениями обычно используют ALRM с этой целью и обновление вместо того, чтобы умереть, когда они получают тот сигнал.

doalarm() { perl -e 'alarm shift; exec @ARGV' "$@"; }

doalarm ${NUMBER_OF_SECONDS_BEFORE_ALRMING} program arg arg ...

Если Вы не можете или не использовать одну из этих программ (который действительно должен был быть включен с основными базовыми утилитами Unix 30 лет назад!), затем лучшим, который можно сделать, является ужасный взлом как:

 command & pid=$!
 { sleep 10; kill $pid; } &

Это, поскольку Вы скоро обнаружите, произведет настоящую путаницу независимо от того, умерло ли условие тайм-аута или нет, если оно выполняется в интерактивной оболочке. Чистка его не является чем-то стоящим мое время. Кроме того, это не может использоваться ни с какой командой, которая требует приоритетного терминала, как вершина.

Возможно сделать что-то подобное, но сохранить команду на переднем плане:

 bash -c '(sleep 10; kill $$) & exec command'

kill $$ уничтожил бы оболочку, за исключением того, что должностное лицо заставляет команду принимать PID оболочки. Необходимо использовать удар-c так, чтобы оболочка вызова не была заменена; в ударе 4, возможно использовать подоболочку вместо этого:

 ( cmdpid=$BASHPID; (sleep 10; kill $cmdpid) & exec command )

Сценарий оболочки "тайм-аут" (чтобы не быть перепутанным с командой 'тайм-аут') использует второй подход выше. Это сразу имеет преимущество работы (никакая потребность в компиляции программы), но имеет проблемы, например, с программами, читая стандартный вход.

Просто используйте тайм-аут или doalarm вместо этого.В самом деле.

6
27.01.2020, 20:34
  • 1
    coreutils timeout (с небольшим хакерством из-за природы процесса я хочу управлять), кажется, делает большой, спасибо! –  a CVn 27.09.2011, 22:33
  • 2
    я использовал сценарий жемчуга один лайнер. Я встретился с нечетной трудностью: это, кажется, не работает, когда команда является функцией удара. doalarm 7200 echo "Cool" работы отлично, testfun () { echo $1 } ; testfun "Cool" работы отлично, но doalarm 7200 testfun "Cool" не работает. Спасибо за любые предложения. –  Etienne Low-Décarie 17.05.2013, 22:08

В достаточно недавней системе Linux (более точно, с GNU coreutils ≥8.5), это столь же просто как

timeout 2m myprogram

Только с функциями оболочки POSIX можно приблизиться, но существует небольшое состояние состязания, если тайм-аут происходит (в теории, PID второго фонового процесса мог бы быть снова использован незадолго до kill $s выполняется).

myprogram <>/dev/tty & p=$!;
{ sleep 120; kill $p; } & s=$!;
wait $p; kill $s

Существует хороший путь, который работает, даже когда Вы должны произвести из программы без состояния состязания. Это - изящный прием с помощью способности отправить сигнал в процесс группы. Это происходит из-за Stéphane Gimenez.

sh -ic '{ myprogram <>/dev/tty; kill 0; } |
        { sleep 120; kill 0; }'
6
27.01.2020, 20:34

Хотел бы добавить кое-что к решению, данному Жилем «ТАК -перестань быть злым». Я храню его в своем фильтре башскрипта. В случае, если я что-то ожидаю, и если время истекло без какого-либо журнала, это выглядит плохо, поэтому я хотел бы немного улучшить его, как показано ниже:

timeout 3s sleep 1 || echo "sleep exceeded time"

Это даст журнал только в случае сбоя, иначе ничего.

1
05.02.2021, 15:45

Теги

Похожие вопросы