Script is executed from the command line, but crontab does not work

I am still learning Bash and I have a problem with my script. I want to filter out some calls with this script, which analyzes the call log every 2 minutes as a cronjob. The problem is that I can start it manually, but it does not work when cron starts automatically. I do not know why. He is shouting something about permissions, so I kind of fixed the script, so if this seems dirty, I'm really sorry.

#!/bin/bash YESTERDAY=$((`date +'%s'`-86400)) AYER=`date -d "1970-01-01 $YESTERDAY sec" +"%Y%m%d"` FECHA=`date +"%Y%m%d"` FILENAME="$FECHA.log" FILE_LINE="$FECHA.last" FILE="/apps/sittel/rawdata/mitel.$FECHA" # Limpiar carpeta tmp if [ -e "tmp/$AYER.lnum" ]; then rm tmp/${AYER}.* fi # Si existe el archivo con el numero de laultima linea se procesa if [ -e "tmp/$FECHA.lnum" ]; then # Se lee el numero de la linea y se extrae un archivo con las lineas apartir # de la ultima busqueda que se hizo, posteriormente se les hace un grep while read line do tail -n +$line $FILE > "tmp/$FECHA.hal" done < "tmp/$FECHA.lnum" cd tmp grep -n " 00[0|2-9][0-9]\{4,\}" "tmp/$FECHA.hal" > "tmp/${FECHA}.new" grep -n " 900[0|2-9][0-9]\{4,\}" "tmp/$FECHA.hal" >> "tmp/${FECHA}.new" cd .. echo `pwd` cat tmp/${FECHA}.new >> logs/$FILENAME else # Este caso es la primera vez que se ejecuta, verifica si el log ya existe # de ser asi, lo elimina para evitar duplicados if [ -e "logs/$FILENAME" ]; then rm "logs/$FILENAME" fi # Se realiza un grep en el archivo indicado y se marca el archivo de salida # se busca todos los numeros k empiecen con 00 seguidos de 0 a 9 execpto el 1 cd tmp grep -n " 00[0|2-9][0-9]\{4,\}" $FILE>"${FECHA}.new" grep -n " 900[0|2-9][0-9]\{4,\}" $FILE>>"${FECHA}.new" cat ${FECHA}.new >> $FILENAME mv $FILENAME ../logs cd .. fi cp "tmp/${FECHA}.new" "tmp/message.txt" echo "Mensaje" | mail -s "$SUBJECT" "$EMAIL" < "tmp/message.txt" fi if [ -e "tmp/${FECHA}.new" ]; then rm "tmp/${FECHA}.new" fi tail -n1 "logs/$FILENAME" > "tmp/$FILE_LINE" IFS=$':' while read line do DATOS=($line) LINE_NUMBER=${DATOS[0]} echo $LINE_NUMBER > "tmp/$FECHA.lnum" done < "tmp/$FILE_LINE" unset IFS 

and this is what the system prints:

 /apps/sittel/Alarma/callAlarm: line 56: cd: tmp: No such file or directory mv: cannot move `20110712.log' to `../logs': Permission denied /apps/sittel/Alarma/callAlarm: line 69: tmp/20110712.last: No such file or directory /apps/sittel/Alarma/callAlarm: line 77: tmp/20110712.last: No such file or directory 
+1
source share
3 answers

Your script assumes that it is run from a specific directory (note that almost every path is a relative path, not an absolute path). cron used to run from another directory.

Correction

If the script works when you run it from the directory in which it lives, add the following to the top of the script:

 mydir=$(dirname "$0") && cd "${mydir}" || exit 1 

Explanation

$0 is the (possibly relative) name of the shell script file. Given the file name, the dirname command returns a directory containing the file name.

So, this line changes directories to the directory containing the script, or exits with an error code if dirname or cd fails.

+2
source

It looks like you might need cd in the correct directory at the beginning of your script.

Put a pwd at the beginning, then exit and look at the cron output to see where you're running from. It is also likely that you have less PATH when working under cron, but it should still have access to tail and grep .

0
source

It seems that you accept a specific start directory and create the tmp . But when you run it as a cron job, it starts elsewhere. Thus, the cd command in your bash script start may interfere with you. You can easily test using full path names when you are cd or rm or something else.

For instance,

 if [ -e "tmp/$AYER.lnum" ]; then rm /home/username/tmp/${AYER}.* fi # Si existe el archivo con el numero de laultima linea se procesa if [ -e "/home/username/tmp/$FECHA.lnum" ]; then # Se lee el numero de la linea y se extrae un archivo con las lineas apartir # de la ultima busqueda que se hizo, posteriormente se les hace un grep while read line do tail -n +$line $FILE > "/home/username/tmp/$FECHA.hal" done < "/home/username/tmp/$FECHA.lnum" cd /home/username/tmp grep -n " 00[0|2-9][0-9]\{4,\}" "/home/username/tmp/$FECHA.hal" > "/home/username/tmp/${FECHA}.new" 

etc.

0
source

Source: https://habr.com/ru/post/954567/


All Articles