Where can I set environment variables that crontab will use?

后端 未结 17 1535
说谎
说谎 2020-11-22 05:47

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,

相关标签:
17条回答
  • 2020-11-22 06:12

    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!

    0 讨论(0)
  • 2020-11-22 06:14

    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
    ...
    
    0 讨论(0)
  • 2020-11-22 06:17

    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"
    
    0 讨论(0)
  • 2020-11-22 06:19

    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
    
    0 讨论(0)
  • 2020-11-22 06:23

    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

    0 讨论(0)
  • 2020-11-22 06:24

    Have 'cron' run a shell script that sets the environment before running the command.

    Always.

    #   @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
    #   Crontab file for Home Directory for Jonathan Leffler (JL)
    #-----------------------------------------------------------------------------
    #Min     Hour    Day     Month   Weekday Command
    #-----------------------------------------------------------------------------
    0        *       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
    1        1       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/daily
    23       1       *       *       1-5     /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
    2        3       *       *       0       /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
    21       3       1       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/monthly
    

    The scripts in ~/bin/Cron are all links to a single script, 'runcron', which looks like:

    :       "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
    #
    #       Commands to be performed by Cron (no debugging options)
    
    #       Set environment -- not done by cron (usually switches HOME)
    . $HOME/.cronfile
    
    base=`basename $0`
    cmd=${REAL_HOME:-/real/home}/bin/$base
    
    if [ ! -x $cmd ]
    then cmd=${HOME}/bin/$base
    fi
    
    exec $cmd ${@:+"$@"}
    

    (Written using an older coding standard - nowadays, I'd use a shebang '#!' at the start.)

    The '~/.cronfile' is a variation on my profile for use by cron - rigorously non-interactive and no echoing for the sake of being noisy. You could arrange to execute the .profile and so on instead. (The REAL_HOME stuff is an artefact of my environment - you can pretend it is the same as $HOME.)

    So, this code reads the appropriate environment and then executes the non-Cron version of the command from my home directory. So, for example, my 'weekday' command looks like:

    :       "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
    #
    #       Commands to be done each weekday
    
    # Update ICSCOPE
    n.updics
    

    The 'daily' command is simpler:

    :       "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
    #
    #       Commands to be done daily
    
    # Nothing -- most things are done on weekdays only
    
    exit 0
    
    0 讨论(0)
提交回复
热议问题