Comando timeout: Limitando o Tempo de Execucao de Comandos

Comando timeout: Limitando o Tempo de Execucao de Comandos

O Que Voce Vai Aprender

  • Como limitar quanto tempo um comando executa com timeout
  • Como parar automaticamente um comando que "trava e nunca retorna"
  • Como detectar um timeout usando o status de saida 124
  • Como forcar o encerramento de um processo teimoso que ignora SIGTERM com -k

Resumo Rapido (os padroes para memorizar primeiro)

  • Executar com limite de tempo -> timeout 10 command (para apos 10 segundos)
  • Adicionar unidade se preferir -> timeout 30s / timeout 5m / timeout 1h
  • Detectar um timeout -> status de saida 124 significa que expirou
  • Ainda nao para -> timeout -k 5 10 command (kill forcado apos periodo de graca)

1. O Que e o Comando timeout?

Conclusao: timeout encerra automaticamente um comando quando ele excede o limite de tempo que voce definiu. E a ferramenta ideal para prevenir travamentos.

Lina: Senpai, executei um comando de download e ele simplesmente nunca terminou. A tela congelou e tive que apertar Ctrl+C. Essa e a unica forma de parar?
Veterano Linny: E exatamente ai que o timeout ajuda. Ele permite definir um limite de tempo: "execute este comando por no maximo N segundos, e pare automaticamente se ultrapassar."
Lina: Entao eu nao preciso apertar Ctrl+C eu mesma? Ele para sozinho?
Veterano Linny: Exato. Isso evita que um comando fique "travado e executando." Isso importa especialmente para scripts que executam automaticamente, ou cron jobs - um comando travado que fica ativo causa problemas reais. timeout e sua rede de seguranca.

A ideia basica do timeout

timeout 10 command
        |   |
        |   o comando que voce quer executar
        limite de tempo (segundos)

"Terminar dentro de 10 segundos e ele encerra normalmente; ultrapassar e ele e forcadamente parado."

2. Por Que Voce Precisa do timeout?

Conclusao: Um comando que trava esperando rede ou em um loop infinito pode congelar todo seu script. timeout previne isso.

Lina: Mas se um comando funciona corretamente, voce nao precisa realmente de um limite de tempo, certo?
Veterano Linny: Normalmente, nao. O problema sao comandos onde voce nao sabe quando vao terminar - conectar a um servidor que nao responde, pingar um host que sumiu, ou um loop que voce escreveu errado. Esses podem nunca retornar.
Lina: E exatamente o que aconteceu com meu download...
Veterano Linny: Se um humano esta observando, ele pode apertar Ctrl+C. Mas um cron job ou script de automacao nao tem ninguem observando. O processo travado fica ali e o proximo passo nunca comeca. Com timeout voce define um limite superior, entao no pior caso ele "desiste apos N segundos e segue em frente."

Um comando travado deixado sozinho pode consumir memoria ou slots de processo, ou causar execucoes sobrepostas de cron. "Colocar um limite de tempo em qualquer coisa que pode nao terminar" e a forma segura de operar.

3. Uso Basico (Especificando o Tempo)

Conclusao: A forma e timeout DURACAO comando. Um numero simples significa segundos; adicione s/m/h/d para unidades.

A forma mais basica e:

$ timeout 10 sleep 30

sleep 30 normalmente espera 30 segundos. Mas com timeout 10, ele e parado apos 10 segundos.

Lina: Terminou em 10 segundos mesmo sendo sleep 30. Parou antes dos 30 segundos prometidos.
Veterano Linny: Exato, e o limite de tempo em acao. Um numero simples significa segundos. Voce tambem pode adicionar uma unidade para ficar mais claro.

Voce pode anexar uma unidade (sufixo) a duracao.

$ timeout 30s command    # 30 segundos
$ timeout 5m command     # 5 minutos
$ timeout 1h command     # 1 hora
$ timeout 2d command     # 2 dias

Unidades de duracao (sufixos)

Forma Significado
10 10 segundos (sem unidade = segundos)
30s 30 segundos
5m 5 minutos
1h 1 hora
2d 2 dias

Decimais tambem funcionam (timeout 0.5 command para 0,5 segundos).

4. Detectando Timeouts com Status de Saida 124

Conclusao: Quando timeout interrompe um comando, o status de saida e 124. Se echo $? mostrar 124, houve timeout.

Quando timeout para um comando porque o tempo expirou, o status de saida se torna 124. Verificar isso permite detectar um timeout mecanicamente.

$ timeout 1 sleep 10
$ echo $?
124
Lina: O numero 124 apareceu. Entao esse e o sinal de um timeout.
Veterano Linny: Exatamente. Por outro lado, se o comando termina normalmente dentro do tempo, seu proprio status de saida e retornado - 0 para sucesso, por exemplo. Entao verificar 124 diz se foi "cortado no meio" ou "terminou corretamente."

Se terminar a tempo, o proprio status do comando e retornado.

$ timeout 10 sleep 1
$ echo $?
0

Status de saida que valem conhecer

Valor Significado
124 Cortado por um timeout
125 O proprio comando timeout falhou
126 Comando encontrado mas nao conseguiu executar
127 Comando nao encontrado
137 Morto forcadamente pelo sinal KILL (-k) (128 + 9)

Por agora, apenas lembre "124 = timeout."

5. Forcando o Encerramento de Processos Teimosos com -k

Conclusao: timeout envia SIGTERM por padrao. Se isso for ignorado, use -k DURACAO para enviar SIGKILL apos um periodo de graca e parar com certeza.

Lina: Ouvi dizer que as vezes um comando nao para mesmo apos timeout. Por que?
Veterano Linny: Boa pergunta. Quando o tempo expira, timeout primeiro envia um SIGTERM (um pedido educado para encerrar) ao comando. Mas alguns programas ignoram esse pedido, entao nao param.
Lina: Entao mesmo quando voce pede para "por favor parar," ele nao obedece... O que fazer entao?
Veterano Linny: E ai que voce usa -k (kill-after). Voce configura uma abordagem em duas etapas: "se ainda nao parou N segundos apos o primeiro pedido, mate forcadamente (SIGKILL)."
$ timeout -k 5 10 command

Isso significa:

  • Primeiro, apos 10 segundos, enviar SIGTERM (o pedido educado) ao comando
  • Se ainda nao parou apos mais 5 segundos, enviar SIGKILL (kill forcado)

Como -k (kill-after) funciona

timeout -k 5 10 command
         |  |
         |  o limite real de tempo (10s) -> SIGTERM
         graca extra (5s) -> SIGKILL se ainda estiver executando

Um programa nao pode recusar SIGKILL. E o ultimo recurso quando voce precisa para-lo com certeza.

SIGKILL (kill forcado) para o processo sem dar chance de limpar. Um arquivo sendo gravado pode ficar corrompido, entao tente um timeout simples (SIGTERM) primeiro e use -k como backup apenas quando nao parar.

6. Especificando o Sinal (-s)

Conclusao: Use -s para alterar o sinal enviado. Se quiser que o status do proprio comando seja retornado no timeout, use --preserve-status.

Por padrao SIGTERM e enviado, mas voce pode especificar um sinal diferente com -s (--signal).

$ timeout -s SIGINT 10 command

Isso envia SIGINT, o mesmo que Ctrl+C. Alguns comandos encerram mais graciosamente com isso do que com SIGTERM.

Lina: Sinais - sao coisas como SIGTERM e SIGKILL, certo? Existem tipos diferentes?
Veterano Linny: Muitos. Os que voce mais usa com timeout sao o educado SIGTERM (padrao), SIGINT (como Ctrl+C), e o ultimo recurso SIGKILL. Sinais em si vao um pouco mais fundo, entao vamos cobri-los adequadamente em outro artigo (fundamentos do trap).

Quando voce quer que o status de saida do proprio comando seja retornado em vez de 124 no timeout, use --preserve-status.

$ timeout --preserve-status 10 command

Use --preserve-status quando voce se importa mais com o valor que o comando retornou do que se houve timeout. Normalmente e mais simples deixar desligado e verificar 124.

7. Erros Comuns de Iniciantes

Conclusao: E facil confundir a ordem de duracao e comando, o significado de 124 e a ordem de argumentos do -k.

7-1. Invertendo a ordem de duracao e comando

# NG: o comando vem primeiro
$ timeout sleep 30 10

# OK: duracao -> comando
$ timeout 10 sleep 30

A duracao deve sempre vir logo apos timeout. Depois escreva o comando que quer executar. Inverta a ordem e timeout da erro.

7-2. Confundir 124 com um "erro"

Lina: Quando 124 apareceu pela primeira vez, entrei em panico e pensei "o comando quebrou"
Veterano Linny: 124 e na verdade prova de que o timeout fez seu trabalho conforme planejado. Nao e um defeito no comando - significa "nao terminou a tempo, entao cortei como planejado." Sem motivo para panico.

7-3. Pensar que limitou todo o pipeline quando apenas parte foi limitada

# Isto nao limita todo o pipeline
$ timeout 10 grep pattern file | sort

Apenas a parte timeout 10 grep pattern file e limitada; | sort e tratado separadamente. Para envolver um pipeline inteiro de uma vez, use bash -c.

$ timeout 10 bash -c 'grep pattern file | sort'

8. Mini Exercicios: Tente Voce Mesmo

Conclusao: Tres tarefas - cortar, verificar status de saida, kill forcado - para sentir o timeout na pratica.

Lina: Entendi os conceitos. Quero tentar na pratica.
Veterano Linny: Otimo, preparei tres tarefas. Usar sleep torna seguro experimentar.

Tarefa 1: Corte sleep 30 apos 3 segundos.

Mostrar dica

A forma e timeout DURACAO comando. Um numero simples significa segundos.

Resposta exemplo
$ timeout 3 sleep 30

Tarefa 2: Logo apos a Tarefa 1, imprima o status de saida e confirme que e 124 (timeout).

Mostrar dica

O resultado anterior esta em $?.

Resposta exemplo
$ timeout 3 sleep 30
$ echo $?

Ver 124 significa que o timeout funcionou.

Tarefa 3: Escreva um comando que pare sleep 30 com "SIGTERM em 5 segundos, depois SIGKILL se ainda estiver executando 2 segundos depois."

Mostrar dica

A ordem e -k GRACA LIMITE comando.

Resposta exemplo
$ timeout -k 2 5 sleep 30

9. Templates para Copiar e Colar

Conclusao: Tenha os padroes comuns a mao - basico, com unidades, deteccao, kill forcado, pipeline.

Padroes comuns para ter a mao

# Basico: parar apos 10 segundos
timeout 10 command

# Adicionar unidade (segundos / minutos)
timeout 30s command
timeout 5m command

# Detectar timeout (124 significa timeout)
timeout 10 command
echo $?

# Kill forcado se nao parar (10s + 5s de graca, depois SIGKILL)
timeout -k 5 10 command

# Limitar um pipeline inteiro
timeout 10 bash -c 'commandA | commandB'

# Parar com SIGINT (como Ctrl+C)
timeout -s SIGINT 10 command

Proximas Leituras