6 Tips Before You Write Your Next Bash Cronjob

Hi lovely people! 👋 As part of a research I am doing I had to write some bash scripts which were supposed to run every couple of minutes. I made some embarrassing mistakes along the way. I will write about those mistakes in hopes that you don’t make them if and when you write your own bash scripts as cronjobs.

So without wasting any time lets begin!

1. Shebang

I have heard people say since forever that add a shebang at the top of your scripts. This tells the terminal which program to use to run your scripts if your script is an executable file. I wrote code in bash but when I asked the terminal to run it, it threw all sorts of weird errors. At first, I thought my computer has gone rogue but thankfully the problem was simpler. I had forgotten to write this one line at the top of my script:

#! /bin/bash

2. Output Redirection

It is useful and in some cases even required to read the output generated by the background job. You can redirect the output of the script to a log file like this:

*/15 * * * * /home/localadmin/Desktop/tcp_script.sh >> /home/localadmin/Desktop/pipe.log 2>&1
  • */15 makes the command run every 15 minutes
  • >> is redirecting the output to the pipe.log file
  • 2>&1 is making sure that stderr also gets redirected to the same destination (file descriptor) where the standard output (&1) is being redirected

3. Infinite Loops

Oh my God, this one was the most embarrassing issue. I was running a While true loop in my bash script. When you are tired problems like this can often creep in. I wanted some code to run for a while (4 minutes). The problem was that this infinite loop was also a cronjob so cron kept on running a new instance every 15 minutes but the old one never stopped executing.

For this particular problem the solution was to use this:

#! /bin/bash

while [ $SECONDS -lt $end ];

# Other code .....


This makes sure that your loop only runs for 240 seconds. The SECONDS variable keeps track of seconds elapsed since the script started executing.

4. Adding Timeouts

I was using tcpdump to capture wireless packets and store some information about them. The problem was that tcpdump keeps on running for as long as it can until it receives a quit or terminate signal. For my cronjob I wanted it to run for only 4 minutes and after that self-terminate.

The solution was to use the timeout command:

timeout 240 tcpdump <args_for_tcpdump>

240 means that tcpdump will automatically quit after 240 seconds. This can come in handy if you are working with something like tcpdump which you want to terminate when running from within a script.

5. Sudo vs normal user

There are two crontabs. One is for the normal user and one is for root. If your script requires sudo privileges then you need to put your job in root’s crontab.

When you type crontab -e in the terminal you are editing current user’s crontab. However, when you type sudo crontab -e you are editing root’s crontab. root’s crontab jobs are run with sudo privileges.

6. Complete program names

Holy moly this one had me pulling my hair out. I was running some jobs via root’s crontab. The problem was that my bash script contained program names only. For example, I was using ifconfig and I only had this:

ifconfig mon0 up

But I was getting errors that there is no command called ifconfig. As it turns out root’s crontab does not get access to the complete set of environment variables and does not know about all the commands which are typically accessible in a normal terminal session.

Make sure that you either propagate your environment to root’s crontab before the script is run or you prefix every command with the full path to that program on disk. I used the latter method because I knew I wasn’t going to use this script on any other machine so I could get away with hardcoding the paths.

For example, I rewrote the ifconfig command like this:

/sbin/ifconfig mon0 up

Things started working and I was as happy as a clam 😄 See you all in the next post where we will finish up our greenhouse monitoring system! ❤️