Cronjob não está funcionando

2

Eu tenho um script bash que se parece com isso:

#!/bin/sh

PID='ps faux | grep libt | awk 'NR==2{print $2}''
STATUS='ps faux | grep libt | awk 'NR==2{print $1}''
if [ "$STATUS" = "ec2-user" ]; then
 echo "libt already killed"
else
 sudo kill $PID
 echo "libt was killed"
fi
sleep 5
cd /home/ec2-user/libt
sudo ./libt

Eu salvei este arquivo como restart.sh e quando eu corro como ./restart.sh, ele faz o que é suposto (mata o processo de libt e o reinicia). No entanto, agora estou tentando automatizar o processo usando o cron. Então eu fiz um cron job que eu quero rodar a cada 6 horas que se parece com isso

0 */6 * * * /home/ec2-user/restart.sh

Quando eu executo "crontab -l", posso ver essa impressão, então sei que ela foi adicionada corretamente. Devo mencionar que o serviço não tem a capacidade de ser reiniciado, (como "service ... restart") o ID do processo precisa ser encontrado, morto e, em seguida, o script de início precisa ser executado.

Eu descobri que este cronjob não está funcionando, vou logar na caixa e posso ver, olhando para os logs, que não houve reinicialização. O que estou fazendo de errado? O que posso fazer para solucionar problemas?

Qualquer conselho ajudaria, este é meu primeiro trabalho no cron :) Obrigado!

    
por Doug Molineux 09.03.2011 / 06:04

4 respostas

1

Além de permitir que o usuário execute /bin/kill e libt sem uma senha, você provavelmente precisará adicionar a visiblepw à seção Defaults da sudoers arquivo, por exemplo

Defaults     env_reset, visiblepw

e

#allow user to run kill with no password entry
user    ALL=NOPASSWD: /bin/kill, /home/ec2-user/libt/libt
    
por 09.03.2011 / 10:08
4

Presumivelmente, sua intenção com essas linhas é evitar a correspondência do comando grep na saída de ps :

PID='ps faux | grep libt | awk 'NR==2{print $2}''
STATUS='ps faux | grep libt | awk 'NR==2{print $1}''

Você não pode garantir que a segunda linha será a desejada. Você deve eliminar grep usando um truque comum:

ps faux | grep [l]ibt

colocando um caractere entre colchetes, grep procura por "libt" mas não o literal "[l] ibt" porque ele interpreta caracteres entre colchetes como uma lista.

Você deve usar $() para substituição de comandos em vez de backticks. Eles são mais legíveis e mais fáceis de fazer ninhos.

Você também pode obter o nome de usuário e PID usando uma chamada para ps reduzindo as chances de uma condição de corrida, mas você realmente não precisa do nome de usuário, já que você já sabe disso. Você só precisa saber se o processo está sendo executado ou não.

No entanto, ainda há oportunidades para falsos positivos. Se puder, você deve usar pgrep e pkill .

#!/bin/sh
PID=$(pgrep -U ec2-user libt 2>/dev/null)
if [ $? = 0 ]
then
    kill $PID
    echo "libt was killed"
else
    echo "libt already killed"
fi
sleep 5
/home/ec2-user/libt/libt

Por favor, veja Gerenciamento de Processos para mais informações.

    
por 09.03.2011 / 08:37
2

sudo não funciona em um cron job; ele quer solicitar uma senha, pois você não está mantendo seu arquivo de semáforo ativo quando você está desconectado. Considere instalá-lo no crontab do root em vez do seu.

    
por 09.03.2011 / 06:27
2

Você deve tentar substituir essa coisa toda pelo ps-watcher ou Monit muito facilmente. Isso resolveria seus problemas de crontab.

Como alternativa, parece que o geekossauro provavelmente está no caminho certo. Se você quiser manter o script existente, reescreva-o para executar a partir do crontab raiz. Se precisar fazer algo como um usuário diferente, use sudo ou su como root para esse usuário. Isso deve funcionar em torno de qualquer estranheza que você esteja experimentando.

Meu voto sobre isso é definitivamente para monit.

    
por 09.03.2011 / 07:56

Tags