Como executar scripts a cada 5 segundos?

66

Eu tenho um script que precisa ser executado a cada cinco segundos. Eu sei que isso cronpode fazer tarefas a cada minuto, mas existe uma maneira de executar algo a cada segundo?

myusuf3
fonte
3
Que problema você está tentando resolver? Você tem certeza que o cron é a solução certa?
andol
11
Eu sei que o cron não é a solução certa. Eu estava dizendo que não estava em questão. Por favor leia. Estou tentando fazer um script ser executado a cada 5 segundos.
myusuf3
2
Desculpe, acho que entendi a pergunta um pouco errada. Ainda assim, ainda me pergunto se você está tentando resolver o problema certo.
andol
Para as pessoas que vêm aqui procurando como executar algo a cada 5 segundos. Eu recomendo fortemente que você aprenda a programar em tempo real com ferramentas como o socket.io como exemplo.
Brandon Bertelsen
Você descobriu o comando bash sleep? sleep 5pausa (talvez dentro de um loop) por 5 segundos) ...?
precisa saber é o seguinte

Respostas:

64

Cron permite apenas um mínimo de um minuto. O que você pode fazer é escrever um script de shell com um loop infinito que executa sua tarefa e, em seguida, dorme por 5 segundos. Dessa forma, sua tarefa seria executada mais ou menos a cada 5 segundos, dependendo de quanto tempo a tarefa em si leva.

#!/bin/bash

while true; do
  # Do something
  sleep 5;
done

Você pode criar um my-task.sharquivo com o conteúdo acima e executá-lo com sh my-task.sh. Opcionalmente, você pode configurá-lo supervisorcomo um serviço para que ele inicie quando o sistema inicializar, etc.

Realmente parece que você está fazendo algo que provavelmente não deveria estar fazendo. Isso parece errado .

Tommy Brunn
fonte
Pode-se precisar de um cron rodando a cada 5 ou menos segundos para ser usado em raspadores baseados em PHP.
Ravish Kumar
Realmente parece errado. Se você incluí-lo em um trabalho cron, terá trabalhos sobrepostos a cada minuto. Após uma hora, 60 trabalhos serão iniciados a cada 5 segundos. Se você não incluir em um trabalho cron, talvez não seja capaz de saber como interrompê-lo, ou mesmo saber que ele existe.
SeF 4/03
35

Você pode ter um crontrabalho iniciando um script a cada minuto, iniciando assim 12 processos em segundo plano:

* * * * * ~/dostuff.sh

dostuff.sh:

(sleep 5 && /path/to/task) &
(sleep 10 && /path/to/task) &
(sleep 15 && /path/to/task) &
(sleep 20 && /path/to/task) &
(sleep 25 && /path/to/task) &
(sleep 30 && /path/to/task) &
(sleep 35 && /path/to/task) &
(sleep 40 && /path/to/task) &
(sleep 45 && /path/to/task) &
(sleep 50 && /path/to/task) &
(sleep 55 && /path/to/task) &
(sleep 60 && /path/to/task) &

Minha pergunta, no entanto, é o que você faria no EARTH que precisa ser executado a cada 5 segundos?


fonte
11
Bem, isso veio a calhar para mim quando eu fiz um script que verifica repetidamente o /mediadiretório para uma unidade de I ligar para usb para backups automáticos ...
VF1
32
What on EARTH- estatísticas, coleta de lixo, sincronização de arquivos, status online, o nome dele.
ruX
3
Fazendo referência à API externa para dados quase em tempo real. A execução da solicitação a cada 5 s é MUITO melhor do que em todas as exibições de página.
Sergey Kudriavtsev
11
E se o crontab executar o arquivo dostuff.sh duas vezes? Por exemplo, aos 55 segundos, o script é executado, mas ainda não terminou, mas o cron chama o script novamente, o que acontecerá?
TomSawyer
2
ISTO É MAU! Ele potencialmente executa o script mais de uma vez por vez (se demorar mais de 5 segundos), o que pode levar a uma condição de corrida em qualquer arquivo (mesmo temporário) acessado. NÃO FAÇA ISTO se fazer a mesma coisa duas vezes ao mesmo tempo puder causar um problema! (E isso geralmente vai!)
Nonny Moose
27

Basta usar um loop:

while true ; do ./your-script & sleep 5; done

Isso iniciará seu script como um trabalho em segundo plano, durma por 5 segundos e depois repetirá novamente. Você pode usar Ctrl-C para abortá-lo ou usar qualquer outra condição em vez de true, por exemplo, ! test -f /tmp/stop-my-scriptpara fazer um loop apenas enquanto o arquivo /tmp/stop-my-scriptnão existir.

azulado
fonte
Se eu incluir o e comercial, ele diz bash: syntax error near unexpected token ';', então eu o tirei. Eu tenho bash 4.3.11. Meu comando é executado rapidamente, então tudo bem se for executado em primeiro plano.
Tyler Collier
11
@TylerCollier Se você precisasse ./your-scriptexecutar em segundo plano (durante os 5 segundos de sono), você poderia manter &apenas a queda ;. Como &serve ao propósito de separar os comandos, não é necessário (e aparentemente não é permitido) ter ;o mesmo na mesma linha. Outra maneira é escrever o loop em várias linhas (com uma quebra de linha depois &e, opcionalmente, quebras de linha depois doe antes done). Como o ;depois &parece ser um erro de digitação, eu o removi. blueyed: Por favor, sinta-se livre para colocar as ;costas, se você realmente quiser; Nesse caso, sugiro também adicionar uma explicação.
Eliah Kagan
@EliahKagan FWIW, funciona no Zsh (sem erro de sintaxe), mas não é realmente necessário. Obrigado pela edição!
blueyed 12/01
10

Você pode usar o pacote GNU mcron , uma alternativa "Vixie cron".

http://www.gnu.org/software/mcron/manual/mcron.html#Top

"Pode permitir facilmente a especificação de pontos de tempo mais refinados, ou seja, segundos. Em princípio, isso pode ser estendido a microssegundos, mas isso não é implementado."

David
fonte
Era exatamente isso que eu estava procurando. Obrigado!
precisa saber é o seguinte
Por favor, poste isso como resposta à minha pergunta aqui: askubuntu.com/questions/922216/… para que eu possa aceitar sua resposta.
precisa saber é o seguinte
mcronrequer sendmailestar instalado e ativado por padrão. como desativá-lo?
ihsan
2

A configuração mínima no cron é de minutos, não é possível defini-la por 5 segundos. Você pode usar o quartzo, que permite segundos. http://www.quartz-scheduler.org/docs/tutorials/crontrigger.html

Cody Harlow
fonte
Parece que o quartzo não é de código aberto. Isso está correto?
precisa saber é o seguinte
Tem uma versão de código aberto. Ele não tem uma página, basta ir para a página de download. Você não precisa preencher o formulário, basta clicar em me levar para o download.
Cody Harlow
parece ser de código aberto a partir de 2018. github.com/quartz-scheduler/quartz
dogmatic69
2

Use cactos para monitorar o roteador e o switch, mas o Cron permite apenas um período mínimo de um minuto; portanto, se uma porta / dispositivo estiver inativa, não haverá aviso até dois minutos depois.

qttty
fonte
11
Eu recomendo editar esta resposta para expandi-la com detalhes específicos sobre como fazer isso. (Veja também Como faço para escrever uma boa resposta? Para o conselho geral sobre que tipos de respostas são consideradas mais valiosas no Pergunte Ubuntu.)
David Foerster
2

Você pode usar uma unidade de timer SystemD, que acionará um serviço - que você configurou para fazer o que deseja - a cada 5 segundos.

Suponha que sua unidade de serviço seja chamada mystuff.servicee esteja instalada /etc/systemd/system(consulte Serviços do usuário do SystemD se você deseja substituir o crontab de um usuário); em seguida, você pode escrever uma unidade de timer para executar o serviço no momento da inicialização e depois a cada 5 segundos, assim:

/etc/systemd/system/mystuff.timer

[Unit]
Description=my stuff's schedule
[Timer]
OnBootSec=5
OnUnitActiveSec=5
[Install]
WantedBy=timers.target

Em seguida, recarregue a configuração do sistema, ative a unidade de timer e inicie-a.

Guss
fonte
11
É a melhor solução, a única desvantagem é que o cron é muito mais fácil de visualizar e configurar. SystemD é uma dor e começa com sua estrutura de diretórios. Ainda o melhor para um intervalo de 5 segundos
John
O snippet acima não iria em /etc/systemd/system/mystuff.timer em vez de mystuff.service?
Brooks
@ Brooks: sim, minha cópia ruim e ruim e colo do meu lado. Fixo.
Guss
Obrigado ... fico feliz em saber que não sou louco enquanto estou aprendendo systemd :)
Brooks
1

Eu fiz esse tipo de coisa com muito sucesso (e o resultado final é repetido semanas por vez, até que a máquina seja reiniciada). Quanto ao que eu estava fazendo agora, atualizando informações e colocando-as em cache - atualizando a cada 10 segundos.

#!/bin/sh

SLEEP=5

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# do stuff
sleep $SLEEP

# echo and restart...
exec $0

O 'exec $ 0' reinicia o script, mas substitui o script em execução. Ele pode ser iniciado inicialmente com uma linha crontab '@reboot'.

Alister Bulman
fonte
8
Por que não usar um whileloop em vez de reiniciar repetidamente o script?
David Z