Убить процесс в bash, который выполняется дольше указанного времени? - PullRequest
4 голосов
/ 04 октября 2009

У меня есть скрипт завершения работы для Oracle в /etc/init.d dir по команде "стоп" он делает:

su oracle -c "lsnrctl stop >/dev/null"
su oracle -c "sqlplus sys/passwd as sysdba @/usr/local/PLATEX/scripts/orastop.sql >/dev/null"

.. Проблема в том, что lsnrctl или sqlplus не отвечают - в этом случае этот скрипт «stop» просто никогда не заканчивается и сервер не может завершить работу. Единственный способ - это «убить - 9», что.

Я бы хотел переписать скрипт так, чтобы через 5 минут (например), если команда не была завершена - она ​​была прекращена.

Как мне этого добиться? Не могли бы вы привести пример? Я под Linux RHEL 5.1 + bash.

Ответы [ 2 ]

9 голосов
/ 04 октября 2009

Если бы можно было использовать сторонние инструменты, я бы использовал одного из сторонних, предварительно написанных помощников, которых вы можете вызвать из своего скрипта ( doalarm и timeout являются оба упомянуты в записи BashFAQ по теме ).

Если бы сам писал такую ​​вещь без использования таких инструментов, я бы, вероятно, сделал что-то вроде следующего:

function try_proper_shutdown() {
  su oracle -c "lsnrctl stop >/dev/null"
  su oracle -c "sqlplus sys/passwd as sysdba @/usr/local/PLATEX/scripts/orastop.sql >/dev/null"
}

function resort_to_harsh_shutdown() {
  for progname in ora_this ora_that ; do
    killall -9 $progname
  done
  # also need to do a bunch of cleanup with ipcs/ipcrm here
}

# here's where we start the proper shutdown approach in the background
try_proper_shutdown &
child_pid=$!

# rather than keeping a counter, we check against the actual clock each cycle
# this prevents the script from running too long if it gets delayed somewhere
# other than sleep (or if the sleep commands don't actually sleep only the
# requested time -- they don't guarantee that they will).
end_time=$(( $(date '+%s') + (60 * 5) ))
while (( $(date '+%s') < end_time )); do
  if kill -0 $child_pid 2>/dev/null; then
    exit 0
  fi
  sleep 1
done

# okay, we timed out; stop the background process that's trying to shut down nicely
# (note that alone, this won't necessarily kill its children, just the subshell we
# forked off) and then make things happen.    
kill $child_pid
resort_to_harsh_shutdown
6 голосов
/ 02 марта 2012

вау, это сложное решение. вот что-то проще Вы можете отслеживать PID и убить его позже.

my command & #where my command is the command you want to run and the & sign backgrounds it.
PID=$! #PID = last run command.
sleep 120 && doProperShutdown || kill $PID #sleep for 120 seconds and kill the process properly, if that fails, then kill it manually..  this can be backgrounded too. 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...