LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Server (https://www.linuxquestions.org/questions/linux-server-73/)
-   -   bash script runs different when cron executed (https://www.linuxquestions.org/questions/linux-server-73/bash-script-runs-different-when-cron-executed-706038/)

jalder85 02-19-2009 05:53 PM

bash script runs different when cron executed
 
I'm fairly new to cron job, but I have put together a bash script.

When running the bash script itself, it operates as expected. However, when running from cron daemon, it runs a defunct and if output is redirected to an error log I receive:

ls: *.tar.gz: No such file or directory

Here is the contents of the bash script I am trying to use:
Code:

root@linux [/cpbackup/daily]# cat cpanel2mosso.sh
#! /bin/bash
date >> cpanel2mosso.log
echo "---------------------------" >> cpanel2mosso.log

for each in `ls *.tar.gz`; do
DENY=`egrep -c $each cpanel2mosso.deny`;
#echo $DENY;
if [ "$DENY" != "0" ]; then
echo $each "is banned from remote backup" >> cpanel2mosso.log;
echo "---------------------------" >> cpanel2mosso.log;

else
echo $each "Container"`date +%w` >> cpanel2mosso.log;
php cpanel2mosso.php upload $each "Container"`date +%w`;
echo $each "Upload Complete!" >> cpanel2mosso.log;
echo "---------------------------" >> cpanel2mosso.log

fi

done;
date >> cpanel2mosso.log
echo "All files have been backed up" >> cpanel2mosso.log
echo "---------------------------" >> cpanel2mosso.log

Full details of the project (rest of the scripts) can be found here:
http://www.gorillasmashserver.com/node/11

Please let me know if I am missing something simple, or complex...

Thanks!

Jack

chrism01 02-20-2009 07:25 AM

When in cron, always give fullpaths to cmds, as cron's $PATH is minimal, so /bin/date instead of date, /bin/egrep instead of egrep, etc.
Also, a cron job has no default dir; you need to cd into the correct dir first.

chitambira 02-20-2009 07:44 AM

obviously you script wants to list all tar files in a directory (but which one???) First cd into that directory then do your for each in ....
If you are trying to get all tar.gz files on your machine, you can possibly use find

jalder85 02-20-2009 09:38 AM

Hello,

Thank you both for catching that ! :) Wish I caught that before posting :o

Thanks,

Jack

TheLinuxDuck 02-20-2009 11:53 AM

jalder,

don't worry about it :) There are always tricks to things we are new to. I'll give you a few pointers on how I write automated scripts (many will think some of it too much, but I don't think there is such a thing).

I take chrism's "full path" suggestion a little further among other things.

First thing in the script, I identify the logfile:

Code:

#!/bin/bash

LOGFILE="/var/log/backup.log"

This way, everything in the script can use it.

Second, I create a "logEntry" function that basically just dumps out a date-prepended log entry. Very nice and handy for when you need to know specifics about when the log entries were written:

Code:

function logEntry()
{
  while [ "x$1" != "x" ]; do
    echo "`date \"+%F %H:%M\"`: $1" >> $LOGFILE
    shift 1 || break
  done
}

Easy to use, just say what you want to say:
Code:

  logEntry "This thing doesn't work at all"
which looks like
Code:

  2009-02-20 10:48: This thing doesn't work at all
Next, I write a function whose whole purpose is to find which. If it succeeds, it sets "WHICH" to be the full path to the which command. If it fails, it exits the script after writing a log file entry:

Code:

function findWhich()
{
  #  see if it's in any usual place
  for whichloc in /usr/bin/which /bin/which /usr/local/bin/which; do
    if [ -x "$whichloc" ]; then
      #  we found it, so we exit the function and move on
      WHICH="$whichloc"
      return
    fi
  done
  #  we haven't found it.  see if it's in the path now
  WHICH=`which which 2>&1`
  #  check the exit code
  if [ $? != "0" ]; then
    #  we cannot find which, terminate the script
    logEntry "unable to locate which"
    exit 1
  fi
}

Notice the return code check after the `which which` call? I think checking return codes is very important. This helps to track down problems and know when the command failed, especially if the command doesn't return anything.

Next, I'm going to put variable declaractions for every binary I use in the script. However, I want to have a quick and easy way to check whether these assignments worked or failed, so I write a quick function just for testing the return values of these:

Code:

function canWeFindIt()
{
  if [ $? != "0" ]; then
    logEntry "Cannot find command '$1'"
    exit 1
  fi
}

Before defining the command paths, I need to call findWhich, but then I can check for any binary/command I use:

Code:

findWhich

EGREP=`$WHICH egrep`    ; canWeFindIt egrep
PHP=`$WHICH php`        ; canWeFindIt php
LS=`$WHICH ls`          ; canWeFindIt ls

This way, you are guaranteed that all binaries used in the script are valid and installed.

Next, I mark the main part of the script, just for fast visual reference:

Code:

################################ main
#

And now start doing all the normal things you would. Typically if you don't want the output of a binary/command (or don't need it), it is good to dump it to /dev/null:

Code:

$PHP ./script.php >> /dev/null 2>&1
If you don't know the 2>&1 part, this is very handy. As you know there are two output streams: standard out, and standard error. Standard out is 1 and standard error is 2. This command basically tells the script to route all stderr output into stdout. The reason for this is because the >> /dev/null only catches stdout, not stderr.

Here is an example:

If you issue the "which ls" command, it will echo something like "/bin/ls". If you add the >> /dev/null, as "which ls >> /dev/null", it will return nothing. But, if you change ls to something random letter combo that is definitely not a binary, like "which fdsasdfdsas >> /dev/null", notice now we DO have output, and it was not dumped into /dev/null. Because it is stderr output. If you add our handy dandy output stream redirection: "which fdsasdfdsas >> /dev/null 2>&1"

Now nothing.

Very nice to keep unwanted output from log files and such when doing script automation.

Anyway, I hope these things help you and if not, maybe I taught you something. If not, maybe I'll teach something to someone else who reads this. :)


All times are GMT -5. The time now is 07:49 PM.