Подтвердить что ты не робот

Убить процесс после заданного времени bash?

У меня есть script, который пытается подключиться к БД с помощью другой программы, а тайм-аут (2.5 мин) программы - длинный. Я хочу добавить эту функциональность в script.

Если требуется подключение дольше, чем через 5 секунд, запустите процесс Else убить процесс сна/убийства.

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

DB_CONNECTION_PROGRAM > $CONNECTFILE &
pid=$! 
(sleep 5; kill $pid) &
sleep_pid=$!
wait $pid

# If the DB failed to connect after 5 seconds and was killed
status=$? #Kill returns 128+n (fatal error)
if [ $status -gt 128 ]; then
    no_connection="ERROR: Timeout while trying to connect to $dbserver"
else # If it connected kill the sleep and any errors collect
    kill $sleep_pid
    no_connection=`sed -n '/^ERROR:/,$p' $CONNECTFILE`
fi
4b9b3361

Ответ 1

Я не знаю, идентичен ли он, но я исправил аналогичную проблему несколько лет назад. Однако я программист, а не системный администратор, похожий на Unix, поэтому принимайте следующее с солью, потому что мой Bash -fu может быть не таким сильным...

В основном я сделал fork, fork и fork:)

Недостаточно памяти После того, как я основал свой старый код (который я удивительно все еще использую ежедневно), потому что моя память не была достаточно хороша, в Bash она немного походила на это:

commandThatMayHang.sh 2 > /dev/null 2>&1 &    (notice that last '&', we're forking)
MAYBE_HUNG_PID=$!
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 &   (we're forking again)
SLEEP_AND_MAYBE_KILL_PID=$!   
wait $MAYBE_HUNG_PID > /dev/null 2>&1
if [ $? -eq 0 ]
    # commandThatMayHand.sh did not hang, fine, no need to monitor it anymore
    kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1
fi

где sleepAndMaybeKill.sh сбрасывает количество времени, которое вы хотите, а затем убивает commandThatMayHand.sh.

Таким образом, в основном два сценария:

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

  • команда блокируется, убийца заканчивает убийство команды

В любом случае вам гарантируется либо успешное выполнение сразу после выполнения команды, либо после сбоя.

Ответ 2

Там утилита GNU coreutils, называемая тайм-аутом: http://www.gnu.org/s/coreutils/manual/html_node/timeout-invocation.html

Если у вас есть это на вашей платформе, вы можете сделать:

timeout 5 CONNECT_TO_DB
if [ $? -eq 124 ]; then
    # Timeout occurred
else
    # No hang
fi

Ответ 4

Вы хотите, чтобы сообщение об ошибке не было напечатано, если процесс еще не запущен? Затем вы можете просто перенаправить stderr: kill $pid 2>/dev/null.

Вы также можете проверить, продолжает ли процесс:

if ps -p $pid >/dev/null; then kill $pid; fi

Ответ 5

Вы можете установить тайм-аут через 2 часа и перезапустить javaScriptThatStalls 100 раз таким образом в цикле

seq 100|xargs -II timeout $((2 * 60 * 60)) javaScriptThatStalls