Mate um processo se ficar quieto por um certo período de tempo

9

Eu tenho um utilitário que tem um péssimo hábito de ficar quieto e ficar lá, eu já sei quanto tempo no processo ele faz isso, então eu estou usando timeout para lutar contra isso, mas às vezes ele faz isso antes desse tempo. Existe uma ferramenta semelhante a timeout que irá matar o processo se ele parar de direcionar a saída para stdout?

    
por Benjojo 17.02.2014 / 11:46

2 respostas

8

Com zsh , você poderia fazer:

zmodload zsh/system
coproc your-command
while :; do
  sysread -t 10 -o 1 <&p && continue
  if (( $? == 4 )); then
    echo "Timeout" >&2
    kill $!
  fi
  break
done

A ideia é usar a opção -t de sysread para ler a partir de your-command output com um tempo limite.

Note que isso faz com que your-command seja um pipe. Pode ser que your-command comece a armazenar em buffer sua saída quando ela não vai para um terminal, caso em que você pode descobrir que não produz nada em algum momento, mas apenas por causa desse buffer, não porque é pendurou de alguma forma.

Você poderia contornar isso usando stdbuf -oL your-command para restaurar o buffer de linha (se o seu comando usar stdio) ou usar zpty em vez de coproc para falsificar uma saída de terminal.

Com bash , você deve confiar em dd e GNU timeout , se disponível:

coproc your-command
while :; do
  timeout 10 dd bs=8192 count=1 2> /dev/null <&${COPROC[0]} && continue
  if (($? == 124)); then
    echo Timeout >&2
    kill "$!"
  fi
done

Em vez de coproc , você também pode usar a substituição de processos:

while :; do
  timeout 10 dd bs=8192 count=1 2> /dev/null <&3 && continue
  if (($? == 124)); then
    echo Timeout >&2
    kill "$!"
  fi
done 3< <(your-command)

(isso não funcionará em zsh ou ksh93 porque $! não contém o pid de your-command ).

    
por 17.02.2014 / 12:12