Timeout 'idql' em ksh

2

Abaixo está meu trecho de código.

idql -n $REPOSITORY_NAME.$cs -Udmadmin -P"" -R$DM_SCRIPTS/test.api > /dev/null 2>&1
    if [ $? != 0 ]; then
      echo "   \c"
      echo "ERROR: Cannot connect to: $REPOSITORY_NAME.$cs on $HOST"
    else
      echo "   Successfully connected to: $REPOSITORY_NAME.$cs"
    fi

Isto é da lógica principal que usamos para monitorar nosso serviço. Mas muitas vezes vemos nosso serviço sendo suspenso e, assim, a primeira linha do snippet acima fica suspensa e não prossegue depois disso. Devido a isso, não podemos pegar essa condição de 'serviço suspenso'.

Mais importante ainda, temos que manter as verificações das condições existentes (especificadas nas declarações condicionais if-else) e, além disso, temos que verificar o estado 'suspenso'. Se o comando idql demorar mais de 5 segundos, podemos supor que ele está suspenso.

    
por Vishnu 07.09.2012 / 05:12

3 respostas

2

Acho que você deseja o comando timeout , que faz parte de coreutils e deve estar disponível no seu sistema

Para matar o comando após 5 segundos, mude para:

timeout 5 iqdl -n $REPOSITORY_NAME.$cs ...

Se você não tem o coreutils , pode baixá-lo, criá-lo e instalá-lo aqui: link

Veja também: link

    
por 07.09.2012 / 09:21
1

Consegui modificar a solução em link para corresponder à minha exigência.

Eu testei e isso é perfeito para mim. Eu agradeço toda sua ajuda.

#!/bin/ksh

WAITTIME=5

# run the idql command in the background, discarding any output
idql -n $REPOSITORY_NAME -Udmadmin -P"" -R"$DM_SCRIPTS/test.api" >/dev/null 2>&1 &
IDQL_PID=$!

# set up a timeout that will kill the idql command when 
# $WAITTIME seconds has passed, unless it has completed before that.
(sleep $WAITTIME; kill $IDQL_PID 2>/dev/null) &
TIMEOUT_PID=$!

# wait for the idql command to either complete or get killed; read its return status
wait $IDQL_PID
RESULT=$?

# if the timeout is still running, stop it (ignore any errors)
kill $TIMEOUT_PID 2>/dev/null

# read the return status of the timeout process (we don't need it 
# but running the wait function prevents it from remaining as a 
# zombie process)
wait $TIMEOUT_PID

if [ $RESULT -eq 1 ];then
    echo "something is wrong with $REPOSITORY_NAME, It seems to be down. Result - $RESULT"
elif [ $RESULT -eq 143 ];then
    echo "Attention!!! ***$REPOSITORY_NAME seems to be HUNG*** Result - $RESULT"
else
    echo "$REPOSITORY_NAME seems to be OK. Result - $RESULT"
fi
    
por 09.09.2012 / 13:35
0

Se idql usa o tempo de CPU em um loop quando é interrompido, você pode limitar o tempo total da CPU:

( ulimit -t 5;
  idql -n $REPOSITORY_NAME.$cs -Udmadmin -P"" -R$DM_SCRIPTS/test.api > /dev/null 2>&1 )

Se idql for bloqueado por algum outro motivo (por exemplo, um deadlock), você terá que fazer esse tempo limite na hora do relógio de parede. Aqui está uma solução devido a Stéphane Gimenez , ligeiramente adaptado para obter o status de saída do comando idql .

ret=$(sh -ic '{ { idql -n "$REPOSITORY_NAME.$cs" -Udmadmin -P"" -R"$DM_SCRIPTS/test.api" > /dev/null 2>&1;
                  echo $? >&3;
                  kill 0; } |
                { sleep 5; kill 0; } }' </dev/null 3>&1 2>/dev/null)
if [ -z "$ret" ]; then
  echo "timed out"
elif [ "$ret" -ne 0 ]; then
  echo "error $ret"
else
  echo "ok"
fi

Explicação:

  • Inicie um shell interativo ( sh -i ). Como esse shell é interativo, ele está em seu próprio grupo de processos .
  • O subshell executa dois comandos conectados juntos. Isso permite que ambos os comandos sejam executados em paralelo dentro do mesmo grupo de processos.
  • Ambos os comandos terminam com kill 0 , que mata todos dentro do grupo de processos. Qualquer comando que termine primeiro ( idql ou sleep ) irá matar o outro.
  • Imprime o status de retorno de idql no descritor de arquivo 3, para que ele não passe pelo canal. O descritor de arquivo 3 é redirecionado para o descritor de arquivo 1 no shell externo, para que a saída desse fd seja capturada pela substituição do comando.
  • Redirecione o erro padrão do shell interativo para /dev/null para não exibir nenhuma mensagem "Terminada" do shell interno. Se você quiser ver a saída de erro de idql , precisará redirecioná-la ( idql 2>&4 em vez de idql 2>/dev/null e adicionar 4>&2 antes do 2>/dev/null de sh -i ).
  • Redireciona a entrada padrão do shell interativo de /dev/null para que ele não acabe lendo os comandos do terminal se você pressionar Ctrl + C .
por 08.09.2012 / 01:13