BashScript funciona no Terminal, mas não no CronTab

1

Eu tenho um monte de CronJobs, e eles funcionam bem, exceto por um. Procurei em muitos fóruns e sites e tentei uma combinação de coisas, mas nada funcionou.

Reescrevendo a pergunta é:

Q: O bashscript funciona sem problemas no terminal. Mas com o CronJob não funciona de todo.

A última coisa que fiz para depurar é a seguinte:

1) Verificado se o Cron Daemon está em execução ( ps ax | grep ) = está funcionando

2) Fez um trabalho extra para (re-teste) enviar um e-mail para mim a cada minuto ( * * * * * echo "hello" | mail -s "subject" [email protected] ) = funcionou bem

3) Eu corri meu script bash através do terminal como um standalone = funcionou bem

4) Eu verifiquei grep CRON /var/log/syslog para quaisquer erros = parece bom / sem erros

5) Verificado por permissões, etc. = sem problemas com permissões

6) O caminho do arquivo para o script bash para a tarefa cron parece bem

#!/bin/bash

#When adding any additional machines make sure there are two files
#within the directory. MACHINE_NAMEMACHINE_NUMBER_initial_time.txt
#and MACHINE_NAMEMACHINE_NUMBER_old_ignition_value.txt

#./engine_switch_check.txt MACHINE_NAME MACHINE_NUMBER

echo 'date +%T' >> test.txt

./engine_switch_check.txt MXE 065
./engine_switch_check.txt TMX5BP 001
./engine_switch_check.txt MX3 122
./engine_switch_check.txt TMX 098

e o engine_switch_check.txt:

#!/bin/bash

mc_id="$1"        #-->eg: TMX
mc_no="$2"        #-->eg: 098
echo "$mc_id $mc_no"

#echo "1--$mc_id$mc_no-DATAFILE.txt"
mc_fname=$mc_id$mc_no'_old_ignition_value.txt'
echo $mc_fname


#old_ignition_value=$(sed -n '1p' $mc_fname)
#echo "2--$old_ignition_value"
#old_ignition_value=$(sed -n '1p' $mc_id$mc_no'DATAFILE.txt')
#echo "3--$old_ignition_value"
new_ignition_value='get values from the terminal'
old_ignition_value=$(sed -n '1p' $mc_id$mc_no'_old_ignition_value.txt')


echo "Program name: $0"
echo "New Ignition Value: $new_ignition_value"
echo "Old Ignition Value: $old_ignition_value"
echo;echo;echo

#difference_btwn_new_old_ign_values=$(awk '{print $1-$2}' <<< "$new_ignition_value $old_ignition_value")

difference_btwn_new_old_ign_values=$(($new_ignition_value - $old_ignition_value))
#difference_btwn_new_old_ign_values= expr new_ignition_value - old_ignition_value

echo "$new_ignition_value"
echo "$old_ignition_value"
echo "$difference_btwn_new_old_ign_values"

if [ "$difference_btwn_new_old_ign_values" -lt "1" ]
then
    > $mc_id$mc_no'_initial_time.txt'
    initial_time='date +"%s"'    
    echo $initial_time >> $mc_id$mc_no'_initial_time.txt'
fi

if [ "$difference_btwn_new_old_ign_values" -ge "5" ]
then
    final_time='date +"%s"'
    initial_time=$(sed -n '1p' $mc_id$mc_no'_initial_time.txt')
    echo;echo;echo "initial time: $initial_time"
    echo "final time: $final_time"
  #initial_time=0000
    time_difference_in_sec=$(( $final_time - $initial_time ))

    echo "time difference in sec: $time_difference_in_sec"

    time_difference_in_min=$(( $time_difference_in_sec / 60 ))


    if [ "$time_difference_in_sec" -le "3600" ]
    then
      email_subject="$mc_id $mc_no switched on $difference_btwn_new_old_ign_values times within $time_difference_in_min minutes"

            'echo -e "Hi there,\n\n$mc_id $mc_no has been switched on $difference_btwn_new_old_ign_values times within the last $time_difference_in_min minutes\n\nCheers," | mail -s "$email_subject" $email_list'

      echo "EMAIL SENT"

: <<'psuedo'

      > $mc_id$mc_no'_old_ignition_value.txt'
      echo $new_ignition_value >> $mc_id$mc_no'_old_ignition_value.txt'

psuedo
    fi  

    if [ "$time_difference_in_sec" -gt "3600" ]
    then

            > $mc_id$mc_no'_initial_time.txt'
            initial_time='date +"%s"'    
            echo $initial_time >> $mc_id$mc_no'_initial_time.txt'


    fi
fi

Recortei os detalhes do e-mail, mas essa linha funciona bem.

Eu honestamente não sei o que mais posso fazer. A única diferença com este arquivo bash é que ele chama outro arquivo 'executável txt' de dentro dele. E ambos os arquivos funcionam muito bem no terminal sozinhos.

Atualização (18/02/2015): Eu tentei ainda mais o CronTab, escrevendo outro script (mais simples) para enviar um timestamp, também registrou o timestamp em um arquivo .txt - que funcionou sem problemas. Eu reescrevi porque estava pensando que talvez o CronTab não estivesse funcionando como deveria.

Para quem está tendo um problema semelhante, estas são algumas opções que você deve considerar: Outras coisas que fiz durante a resolução de problemas (não em ordem)

  • Criado um eco para um arquivo de texto para ver se o programa estava sendo executado
  • Evite usar o sudo crontab -e todos recomendam ficar longe do sudo crontab -e
  • Verificado o caminho do diretório dentro do crontab
  • Leia / releia vários fóruns, leia / releia meu programa repetidas vezes (peça a alguém que entenda de programação para fazer isso, pois os olhos novos podem ver o que você pode perder)
  • Adicionado PATH e SHELL no crontab
  • Adicionadas CronJobs diferentes (atualização mencionada em 18/02/15)
  • Caminho relativo alterado para o caminho completo em todos os programas Isso fez com que funcionasse com o crontab
por 3kstc 17.02.2015 / 03:12

3 respostas

1

A solução que funcionou para mim é que eu mudei all dos caminhos dentro dos meus dois programas a partir de caminhos relativos , por exemplo: ( ./name_of_file.txt ) para full caminhos (ex .: /home/ed/directory/some_more_directory/name_of_file.txt )

Foi apenas isso, ou uma combinação das outras coisas que eu fiz, eu não sei - mas mudar os caminhos do caminho relativo para o caminho completo fez isso.

    
por 18.02.2015 / 05:04
1

A definição de $PATH , como outros sugeriram, é sempre uma boa prática em scripts que podem ser chamados de fora do seu ambiente interativo.

Quando você está chamando os scripts do seu shell, você provavelmente cd para o diretório contendo primeiro. Você também precisa fazer isso aqui.

cron pode executar seu script com um diretório de trabalho de / ou /var , por exemplo, portanto, você precisa usar caminhos completos para programas fora de $PATH ou alterar para o diretório de trabalho adequado. Nesse caso, você desejará alterar os diretórios de trabalho, porque o script grava no disco e parece que deseja que o arquivo de saída resida no mesmo diretório que o script.

Você pode alterar os diretórios na entrada do crontab:

* * * * * cd /home/ed/enginecheck && ./engine.txt

Ou no próprio script (antes de qualquer outro comando):

cd /home/ed/enginecheck

echo 'date +%T' >> test.txt
...
    
por 18.02.2015 / 02:33
0

Eu acho que você precisa definir a variável path no script

Por exemplo

PATH='/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin'
    
por 17.02.2015 / 05:53

Tags