Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

In Linux systems, we can use cron to automate the tasks that run periodically. However, sometimes we need to start the job manually, e.g., for debugging purposes. In such a case, we should take into account the job’s environment.

In this tutorial, we’ll learn how to start the cron job in its proper environment by hand.

2. Providing Variables for Cron Jobs

Let’s notice that cron runs tasks in a non-interactive shell with a very limited number of variables. In addition, we can pass variables to the cron task in several ways:

  • setting the BASH_ENV variable to point to the file which contains definitions of variables. Subsequently, these variables are set for the job
  • setting a variable directly in the crontab file. However, not all Linux distribution support this way
  • exporting a variable in the job’s line

Consequently, let’s check the variables set in these ways with the cron_var_test script:

#!/bin/bash

echo "Variable from file pointed by BASH_ENV = $BASH_ENV_VAR"
echo "Variable from cron                     = $CRON_VAR"
echo "Variable from the job line             = $JOB_VAR"

First, let’s edit the crontab to add our script and define the variables:

$ crontab -l

# some output skipped

BASH_ENV=/home/joe/prj/cron/bash_env_file
CRON_VAR=A_cron_variable
* * * * * export JOB_VAR=A_job_variable; /home/joe/prj/cron/./cron_var_test > /home/joe/prj/cron/cron_var_output

Further, lets assume that /home/joe/prj/cron/bash_env_file contains:

BASH_ENV_VAR="A bash env's variable"

Finally, let’s examine the result:

$ cat cron_var_output
Variable from file pointed by BASH_ENV = A bash env's variable
Variable from cron                     = A_cron_variable
Variable from the job line             = A_job_variable

3. Grabbing the Cron Environment

Now, let’s store the environment that cron provides to the task in the env_var.txt file:

BASH_ENV=/home/joe/prj/cron/bash_env_file
CRON_VAR=A_cron_variable
* * * * * export JOB_VAR=A_job_variable; /usr/bin/env > /home/joe/prj/cron/env_var.txt

In addition, we should make sure that the env command accesses the same variables as the cron_var_test script.

4. Running Script Outside Cron With env

Now let’s start our cron script from the interactive shell, but with the cron’s environment. Thus, let’s use the env command. First, with the i option, we create an empty environment to prevent variables leaks from the current shell. Subsequently, we populate the shell with variables saved in the env_var.txt file:

$ env -i $(cat /home/joe/prj/cron/env_var.txt) /home/joe/prj/cron/cron_var_test
Variable from file pointed by BASH_ENV = A bash env's variable
Variable from cron                     = A_cron_variable
Variable from the job line             = A_job_variable

5. Improvement and Caveat

Let’s notice that this simple way fails if the variable’s value contains space, e.g., CRON_VAR=”A cron variable”. Thus, let’s study the cron_test_bed script:

#!/bin/bash

env_file="/home/joe/prj/cron/env_var.txt"
env_command="/usr/bin/env -i "

while IFS= read -r var
do
  env_command="${env_command} \"$var\" "
done < "$env_file"

/bin/bash -c "$env_command [email protected]"

In detail, we read the variables file line by line. As each line represents a variable definition, we put it into quotes, creating the env invocation env_command. Finally, we run this command with /bin/bash -c. Now, let’s check the result:

$ ./cron_test_bed /home/joe/prj/cron/cron_var_test
Variable from file pointed by BASH_ENV = A bash env's variable
Variable from cron                     = A cron variable
Variable from the job line             = A_job_variable

However, we should be aware that we have very few limitations on the content and form of the variable’s value. As an example, this method will fail on a multiline variable. So, we shouldn’t rely much on completely automatic parsing of variables’ values. Instead, we should inspect the variables on our own.

Finally, let’s notice that env doesn’t parse variables coming from the file pointed out by the BASH_ENV, so they may contain any characters.

6. Conclusion

In this article, we learned how to simulate the cron’s environment. In detail, we manually started the script used normally as the cron job. So, we grabbed the cron’s variables and injected them into an empty shell. Subsequently, we ran the script inside this shell with the env command.

Finally, we mentioned troubles with fully automatic parsing of the environment.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!