Scheduling task with crontab

2 minute read

I think schduling a job with crontab should be easy for me, as I am a veteran linux user, the truth is I don’t know crontab, totally.

Each cronjob has the following syntax:

# +---------------- minute (0 - 59)
# |  +------------- hour (0 - 23)
# |  |  +---------- day of month (1 - 31)
# |  |  |  +------- month (1 - 12)
# |  |  |  |  +---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
  *  *  *  *  *  command to be executed

Adding an entry to crontab is as easy as:

(crontab -l 2>/dev/null; echo "*/5 * * * * /tmp/test.sh") | crontab -

And confirmed it was added correctly with:

crontab -l
# */5 * * * * /tmp/test.sh

So I waited for 1 minute expecting my test script being executed, but I cannot find where is the output of the script, the only log I can find is crontab log in syslog:

# tail -f /var/log/syslog
Jul 27 07:41:01 fdbai-desktop CRON[6859]: (fdbai) CMD (/tmp/test.sh)

I found a solution in askubuntu, here is the new crontab task:

crontab -r # remove task
(crontab -l 2>/dev/null; echo "*/5 * * * * /tmp/test.sh >> /tmp/test.log 2>&1") | crontab -

UPDATE:

The output of crontab jobs are logged into mail:

tail -f /var/mail/fdbai

The log shows the script was not executed correctly, it reports:

/tmp/test.sh: line 3: aapt: command not found

Here is the simplified version of test script:

#!/bin/bash

apkname=$(aapt dump badging Contacts.apk | sed -n "s/.*package: name='\([^']*\).*/\1/p")
if [ "$apkname" == "com.android.contacts" ]; then

	echo "do something"
fi

I installed android sdk in /opt/sdk/build-tools/28.0.3/ and I am pretty sure have $PATH variable set correctly as the script can be executed manually without any problem.

echo $PATH in test script shows that, there is only two items in $PATH, they are:

/usr/bin:/bin

As top rated answer to question Why crontab scripts are not working? said, crontab using different environment, it passes a minimal set of environment variables to the scheduling tasks.

So there are two solutions for this issue, first set $PATH variable in the script, and the second is use absolute path instead:

export PATH=/usr/bin:/bin:/opt/sdk/build-tools/28.0.3

Finally, the script may run more than 5 minutes, so I wanna exit script directly if the previous job has not finished, flock can be used for this purpose, lock file at the beginning of the script will do the trick:

exec 100>/var/tmp/apk.lock || exit 1
flock -n 100 || exit 1
# do some stuff

References