[linux] Where can I set environment variables that crontab will use?

I have a crontab running every hour. The user running it has environment variabless in the .bash_profile that work when the user runs the job from the terminal, however, obviously these don't get picked up by crontab when it runs.

I've tried setting them in .profile and .bashrc but they still don't seem to get picked up. Does anyone know where I can put environment vars that crontab can pick up?

This question is related to linux unix environment-variables crontab

The answer is


You can define environment variables in the crontab itself when running crontab -e from the command line.

LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h  dom mon dow   command

* * * * * sleep 5s && echo "yo"

This feature is only available to certain implementations of cron. Ubuntu and Debian currently use vixie-cron which allows these to be declared in the crontab file (also GNU mcron).

Archlinux and RedHat use cronie which does not allow environment variables to be declared and will throw syntax errors in the cron.log. Workaround can be done per-entry:

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"

Expanding on @carestad example, which I find easier, is to run the script with cron and have the environment in the script.

In crontab -e file:

SHELL=/bin/bash

*/1 * * * * $HOME/cron_job.sh

In cron_job.sh file:

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

Any command after the source of .bash_profile will have your environment as if you logged in.


All the above solutions work fine.

It will create issues when there are any special characters in your environment variable.

I have found the solution:

eval $(printenv | awk -F= '{print "export " "\""$1"\"""=""\""$2"\"" }' >> /etc/profile)


Whatever you set in crontab will be available in the cronjobs, both directly and using the variables in the scripts.

Use them in the definition of the cronjob

You can configure crontab so that it sets variables that then the can cronjob use:

$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello

Now the file /tmp/hello shows things like:

$ cat /tmp/hello 
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016

Use them in the script run by cronjob

You can configure crontab so that it sets variables that then the scripts can use:

$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh

And say script /tmp/myscript.sh is like this:

echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res

It generates a file /tmp/myoutput.res showing:

$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...

Another way - inspired by this this answer - to "inject" variables is the following (fcron example):

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

From help set:

-a Mark variables which are modified or created for export.

Using + rather than - causes these flags to be turned off.

So everything in between set - and set + gets exported to env and is then available for other scripts, etc. Without using set the variables get sourced but live in set only.

Aside from that it's also useful to pass variables when a program requires a non-root account to run but you'd need some variables inside that other user's environment. Below is an example passing in nullmailer vars to format the e-mail header:

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck

Instead of

0  *  *  *  *  sh /my/script.sh

Use bash -l -c

0  *  *  *  *  bash -l -c 'sh /my/script.sh'

For me I had to specify path in my NodeJS file.

// did not work!!!!!
require('dotenv').config()

instead

// DID WORK!!
require('dotenv').config({ path: '/full/custom/path/to/your/.env' })

  • Set Globally env
sudo sh -c "echo MY_GLOBAL_ENV_TO_MY_CURRENT_DIR=$(pwd)" >> /etc/environment"
  • Add scheduled job to start a script
crontab -e

  */5 * * * * sh -c "$MY_GLOBAL_ENV_TO_MY_CURRENT_DIR/start.sh"

=)


Unfortunately, crontabs have a very limited environment variables scope, thus you need to export them every time the corntab runs.

An easy approach would be the following example, suppose you've your env vars in a file called env, then:

* * * * * . ./env && /path/to_your/command

this part . ./env will export them and then they're used within the same scope of your command


I got one more solution for this problem:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

In this case it will pick all the environment variable defined in your $HOME/.profile file.

Of course $HOME is also not set, you have to replace it with the full path of your $HOME.


I tried most of the provided solutions, but nothing worked at first. It turns out, though, that it wasn't the solutions that failed to work. Apparently, my ~/.bashrc file starts with the following block of code:

case $- in
    *i*) ;;
    *) return;;
esac

This basically is a case statement that checks the current set of options in the current shell to determine that the shell is running interactively. If the shell happens to be running interactively, then it moves on to sourcing the ~/.bashrc file. However, in a shell invoked by cron, the $- variable doesn't contain the i value which indicates interactivity. Therefore, the ~/.bashrc file never gets sourced fully. As a result, the environment variables never got set. If this happens to be your issue, feel free to comment out the block of code as follows and try again:

# case $- in
#     *i*) ;;
#     *) return;;
# esac

I hope this turns out useful


You can also prepend your command with env to inject Environment variables like so:

0 * * * *   env VARIABLE=VALUE /usr/bin/mycommand

Setting vars in /etc/environment also worked for me in Ubuntu. As of 12.04, variables in /etc/environment are loaded for cron.


For me I had to set the environment variable for a php application. I resloved it by adding the following code to my crontab.

$ sudo  crontab -e

crontab:

ENVIRONMENT_VAR=production

* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php

and inside doSomethingWonderful.php I could get the environment value with:

<?php     
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"

I hope this helps!


If you start the scripts you are executing through cron with:

#!/bin/bash -l

They should pick up your ~/.bash_profile environment variables


Expanding on @Robert Brisita has just expand , also if you don't want to set up all the variables of the profile in the script, you can select the variables to export on the top of the script

In crontab -e file:

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

In script.sh

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

I'm using Oh-my-zsh in my macbook so I've tried many things to get the crontab task runs but finally, my solution was prepending the .zshrc before the command to run.

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

This task runs every 30 minutes and uses .zshrc profile to execute my node command.

Don't forget to use the dot before the $HOME var.


Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to environment-variables

Using Environment Variables with Vue.js Adding an .env file to React Project Is there any way to set environment variables in Visual Studio Code? Test process.env with Jest How to set environment variables in PyCharm? ARG or ENV, which one to use in this case? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? What is a good practice to check if an environmental variable exists or not? Passing bash variable to jq Tensorflow set CUDA_VISIBLE_DEVICES within jupyter

Examples related to crontab

Run CRON job everyday at specific time How to set a cron job to run every 3 hours mysqldump & gzip commands to properly create a compressed file of a MySQL database using crontab How to install crontab on Centos Running a simple shell script as a cronjob Crontab Day of the Week syntax How to run crontab job every week on Sunday Running a cron job at 2:30 AM everyday How to specify in crontab by what user to run script? Using crontab to execute script every minute and another every 24 hours