Executando este comando em um bash interativo:
$ timeout 1 sleep 2; echo $?
124
retorna124após 1 segundo, conforme esperado e documentado em timeout(1).
No entanto, se eu executar o mesmo que um cron job, ou se eu fornecer isso como uma string de comando para o bash, isso não acontecerá:
$ bash -c "timeout 1 sleep 2; echo $?"
0
Adicionar -i
à invocação do bash não ajuda, nem usar o --foreground
parâmetro timeout(1). Também tentei o mesmo com ksh e zsh, mas sempre obtenho o mesmo resultado, então acho que deve ser algo inerente ao modo como o timeout(1) funciona.
Pesquisei um pouco na rede e descobri que isso poderia ter a ver com a forma como a sinalização ocorre através dos grupos de processos, mas não consegui encontrar uma solução para fazer o tempo limite funcionar conforme o esperado no caso não interativo.
Alguma dica de como eu poderia conseguir isso? Em última análise, o que eu quero é executar um comando no cron que provavelmente será bloqueado para sempre e quero detectar esse caso de maneira confiável.
Responder1
Devido às aspas duplas, $?
está sendo expandidoanteso comando bash é invocado. Está sendo substituído pelo status de saída doanteriorcomando (que foi o primeiro exit $?
)
Uma demonstração rápida
bash -c 'exit 42'
bash -c "timeout 1 sleep 2; echo $?" # => 42
A solução é usaraspas simplespara que o processo bash interativo atual não expanda a variável
bash -c 'timeout 1 sleep 2; echo $?' # => 124
Responder2
Você pode tentar executar o comando assim:
bash -c "timeout 1 sleep 2"; echo $?