POSIX equivalente para o tempo limite do GNU?

13

O comando GNU coreutils timeout é extremamente útil para certas situações de script, permitindo usar a saída de um comando se ele é rápido de ser executado, e ignorá-lo se isso levaria muito tempo.

Como posso aproximar o comportamento básico de timeout usando apenas utilitários especificados POSIX?

(Eu estou pensando que pode envolver uma combinação de wait , sleep , kill e quem sabe o que mais, mas talvez eu esteja perdendo uma abordagem mais fácil.)

    
por Wildcard 06.04.2016 / 01:40

1 resposta

3

Minha abordagem seria esta:

  • Executar comando como processo em segundo plano 1

  • Execute o "temporizador de vigia" como processo de segundo plano

  • Configure um manipulador para interceptar um sinal de terminação no shell pai

  • Aguarde a conclusão de ambos os processos. O processo que termina primeiro envia o sinal de terminação para o pai.

  • O manipulador de armaduras do pai mata ambos os processos em segundo plano por meio do controle do job (um deles já foi terminado por definição, mas esse kill será inofensivo no-op porque não estamos usando PIDs, veja abaixo)

Eu tentei contornar a possível condição de disputa endereçada nos comentários usando os IDs de controle de tarefas do shell (que não seriam ambíguos nessa instância do shell) para identificar os processos em segundo plano a serem eliminados, em vez dos PIDs do sistema.

#!/bin/sh

TIMEOUT=$1
COMMAND='sleep 5'

function cleanup {
    echo "SIGTERM trap"
    kill %1 %2
}

trap cleanup SIGTERM

($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &

wait
echo "End of execution"

Resultado para TIMEOUT=10 (o comando termina antes do watchdog):

$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution

Resultado para TIMEOUT=1 (watchdog termina antes do comando):

$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution

Resultado para TIMEOUT=5 (watchdog e comando terminam "quase" simultaneamente):

./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution
    
por 14.04.2016 / 20:32