Skip to main content

BashScript works from Terminal but not from CronTab [Resolved]

I've got a bunch of CronJobs, and they work fine, except for one. I've looked through a lot of forums and websites, and tried a combination of things but alas nothing has worked.

Rephrasing the question is:

Q: The bashscript works without any problems from the terminal. But with the CronJob it does not work at all.

The last thing I have done for debugging is the following:

1) Checked if the Cron Daemon is running (ps ax | grep) =is working

2) Made an extra chron job to (retest) send out an email to me every minute (* * * * * echo "hello" | mail -s "subject" user@myemail.com) =worked fine

3) I've ran my bash script through the terminal as a standalone =worked fine

4) I've checked grep CRON /var/log/syslog for any errors =looks good/no errors

5) Checked for permissions etc. = no problems with permissions

6) The file path to the bash script for the cron job looks fine

#!/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

and the 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

I've cut out the details regarding the email, but that line works fine.

I honestly don't know what else I can do. The only difference with this bash file is that it calls another 'executable txt' file from within it. And both of these files work great from the terminal by themselves.

Update (18/02/2015): I have further tried the CronTab by writing another (simpler) script to email out a timestamp, also recorded the timestamp into a .txt file - which worked without any problems. I rewrote it because I was thinking maybe the CronTab was not working like it should.

For anyone who is having a similiar problem these are some options you should consider: Other things I did during troubleshooting (not in order)

  • Created an echo out to a text file to see if the program was being run
  • Avoided using sudo crontab -e everyone recommends staying away from sudo crontab -e
  • Checked the directory path within the crontab
  • Read/reread various forums, read/reread my program over and over again (get someone else who understands programming to do it, as fresh eyes can see what you might miss)
  • Added PATH and SHELL in to crontab
  • Added different CronJobs (mentioned update 18/02/15)
  • Changed relative path to full path within all the programs This made it work with the crontab

Question Credit: 3kstc
Question Reference
Asked October 9, 2019
Tags: bash, cron
Posted Under: Unix Linux
12 views
3 Answers

The solution that worked for me is I changed all of the paths within my two programs from relative paths ie: (./name_of_file.txt) to full paths (ie: /home/ed/directory/some_more_directory/name_of_file.txt)

Was it just this, or a combination of the other things I did, I don't know - but changing the paths from relative to full path did it.


credit: 3kstc
Answered October 9, 2019

I think you need to set the path variable in the script

For example

PATH='/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin'

credit: muru
Answered October 9, 2019

Setting $PATH, as others have suggested, is always a good practice in scripts that may be called from outside of your interactive environment.

When you are calling the scripts from your shell, you probably cd to the containing directory first. You'll also need to do that here.

cron may run your script with a working directory of / or /var, for example, so you need to use full paths to programs outside of $PATH, or change to the proper working directory. In this case you will want to change working directories because the script writes to disk and it appears you want the output file to reside in the same directory as the script.

You can change directories in the crontab entry:

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

Or in the script itself (before any other commands):

cd /home/ed/enginecheck

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

credit: zackse
Answered October 9, 2019
Your Answer