0

I'm trying to schedule this script to run every day by using crontb :

#/bin/bash
cd /home/banana/gdrive
DATE=`date +%Y-%m-%d`
mongodump  --gzip --archive=$DATE
./gdrive upload ./$DATE

olddate="$(date "+%Y-%m-%d" -d "9 days ago")"
old2=$(date -d $olddate +%s)
#echo $old2
list="$(./gdrive list)"
#echo $list
ADDR=(${list// / })
ii=0
for i in "${ADDR[@]:5}"; do
    if [ $(($ii % 7)) -eq 0 ]; then
       id=$i
    fi
    if [ $(($ii % 7)) -eq 1 ]; then
       name=$i
       dat=$(date -d $name +%s)
       #echo $dat
       if [ $old2 -ge $dat ]; then
          echo "delete"
          echo $id
          touch $id
          ./gdrive delete $id
       fi
       #echo "name"
       #echo $name
       #echo $id
    fi
    #echo $ii
    #echo $i
    let ii=ii+1
done

crontab entry :

0 2 * * * /home/banana/gdrive/upload.sh

the script runs fine if lunched in a bash console, if it's run by crontab it doesn't reach the end even if i'm not able to find any logged error anywhere.

By simulating the use of the crontab environment as suggested here : https://serverfault.com/questions/85893/running-a-cron-job-manually-and-immediately/85906

i found out that the execution result in an error:

gdrive/upload.sh: 12: gdrive/upload.sh: Syntax error: "(" unexpected

given the fact that the SHELL variable in the crontab environment was set to SHELL=/bin/sh and that the syntax there is bash this sound quite reasonable (even if i'm still confusing on the role of the #/bin/bash on the first line of the script).

The problem is that the same outcome still even after putting SHELL=/bin/bash in the crontab file.

So the question is, what's wrong in this setup ? and how can i schedule this script by using crontab ?

2 Answers 2

3

The shebang that needs to be written includes an exclamation mark.

Try to write #!/bin/bash at the first line of your shell script.

1
  • yes, replacing #/bin/bash with #!/bin/bash solve the error
    – bn89
    Oct 3, 2016 at 10:49
0

Complementing the @torusJKL answer:

Analizing the offending line that says ADDR=(${list// / }), it converts all multiple spaces present in $list to only one space (This construct substitute text within the variable: ${variable//old/new} changes each and all strings 'old' in $variable for the string 'new').

If the resulting string starts and ends with spaces, it results in ADDR=( word1 word2 word3 ), which in Bash creates an array $ADDR[], i.e, ADDR=([0]="word1" [1]="word2" [2]="word3") (confirmed as in the for condition appear all elements ${ADDR[@]}, but using :5 to drop/skip the first four elements). If there are less than five elements, the condition is empty and the for body is skipped.

If there are no surrounding spaces, $ADDR will contain only one single datum ('word1' or 'word1 word2 word3' if there are inner spaces; also could be empty or a single space ' '), then ${ADDR[@]} returns that datum and ${ADDR[@]:5} will always be empty as there are no more than four elements.

The problem were then, that cron by default runs commands with sh and sh does not support arrays, so it responds with the error, not building the $ADDR array as desired. Forcing the interpreter to be Bash with the shebang #!/bin/bash in the very first line solves the issue as @torusJKL said.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.