Executar tarefa periódica usando BASH e o comando watch

0

Estou tentando escrever um script BASH com o propósito de usar o comando watch para monitorar um repositório git local para alterações a partir do ramo remoto e, em seguida, executar uma tarefa.

Digamos que o script se chame task.sh e se pareça com:

watch -n 3000 (git remote update && git status) | \
grep -i "your branch is behind origin/" && \ 
{ "pull changes, run tests, etc." ; }

O que eu postei é mais ou menos o que eu tenho até agora, mas não consigo fazer a última parte funcionar. Em outras palavras, parece não pegar quando eu fiz uma mudança no branch do git. Consegui redirecionar a saída de watch para um arquivo como este watch -n 3000 ls 1>> file.txt , mas usar esse método exigiria a abertura do arquivo, o que acho lento e propenso a erros.

Eu basicamente quero que watch seja executado continuamente até que eu mate o script que o iniciou, embora, se houver um método melhor que watch , isso seria ótimo também.

    
por BlazePascal 04.05.2017 / 00:22

1 resposta

0

Como o DopeGhoti mencionou, cron seria uma escolha muito melhor para isso.

Seu exemplo já tem um intervalo de 50 minutos. Se o intervalo for aceitável por uma hora, muitas distros modernas têm um diretório /etc/cron.hourly . Qualquer coisa nesse diretório com o conjunto de bits executável será executado de hora em hora (a maioria das implementações que vi usa run-parts , que executa os executáveis nesse diretório linearmente pelo nome do arquivo).

Se um intervalo mais curto for obrigatório, recomendo /etc/cron.d . O daemon cron geralmente analisa este diretório diretamente, portanto, não há necessidade de o bit executável ser definido. Você poderia criar um arquivo chamado task com o seguinte conteúdo.

*/30 * * * * root /path/to/task.sh

Os primeiros 5 campos são para o minuto, hora, dia do mês, mês e dia da semana. Neste caso, estamos dando um valor de 30 minutos para o passo. Portanto, esse exemplo específico executará task.sh a cada 30 minutos, a cada hora, a cada dia do mês, a cada ... você entende.

Valores de etapa em 30 minutos no campo de minutos levam à execução em N minutos após a hora, em que N é o valor no campo de minutos.

Veja aqui para uma solução para intervalos ímpares.

Agora, para o código bash ...

O motivo pelo qual isso não está funcionando como esperado é porque grep nunca retorna um valor de saída para ser avaliado por && . Ainda é grep ing a saída de watch .

Isso pode ser visto no exemplo a seguir. O echo e sleep dentro das chaves toma o lugar de watch . Depois que o sleep sair, grep também poderá. A segunda data não é executada até que grep exits e o código de saída possa ser avaliado.

[vagrant@localhost ~]$ date +%s; { echo a; sleep 15; } | grep 'a' && date +%s
1493875975
a
1493875990

Uma maneira de corrigir isso seria mover tudo para estar dentro de watch .

watch -n 15 'bash -c "echo a | grep 'a' && date +%s"'

Outra opção é usar um while-loop de verdade.

[vagrant@localhost ~]$ while :; do echo a | grep 'a' && date +%s; sleep 15; done
a
1493875992
a
1493876007
a
1493876022
^C
    
por 04.05.2017 / 08:20