Re: Python does not get environment variable when using cron.

Discussion in 'Python' started by Cameron Simpson, Aug 18, 2008.

  1. On 17Aug2008 21:25, John Nagle <> wrote:
    > Stephen Cattaneo wrote:
    >> I am attempting to execute an automated test (written in Python) via
    >> cron. I have to check the HOSTNAME variable as part of the test, oddly
    >> under cron the HOSTNAME environment variable is not in the os.environ
    >> dictionary. I know that cron runs in a subshell that does not have all
    >> of the normally set environment variables. HOSTNAME is not one of those
    >> variables, it is set even in cron's subshell. Why doesn't python get
    >> this variable? Is this a bug in python2.4?

    Because $HOSTNAME is a bash specific variable, set by bash but NOT
    EXPORTED! Like $0 and a bunch of other "private" variables, subprocesses
    do not inherit this value. From "man bash":

    Shell Variables
    The following variables are set by the shell:
    Automatically set to the name of the current host.

    Note that "set" does not imply "exported". Only exported vairables are
    seen by subprocesses.

    > Cron doesn't normally use a shell at all. It just runs the
    > requested program in a subprocess. So there's no shell involved,
    > and you don't get a shell-type user environment.

    This statement is false.

    Cron hands _all_ jobs to a shell. From "man 5 crontab":

    The ``sixth'' field (the rest of the line) specifies the command to be
    run. The entire command portion of the line, up to a newline or % char-
    acter, will be executed by /bin/sh or by the shell specified in the SHELL
    variable of the cronfile.

    That's from Vixie cron, but all UNIX crons hand the command part of the
    cron line to a shell, usually /bin/sh.

    You're probably confused by the fact that cron does not invoke "login" shells
    (with their associated initialisation from /etc/profile and $HOME/.profile).

    > If you have
    > a crontab line like
    > 10 3 * * * /usr/bin/python
    > there's no shell.

    Not so. A shell will be interpreting the string "/usr/bin/python", mch as happens when you type this on the command line.

    > You can try
    > 10 3 * * * /bin/sh /usr/bin/python
    > which will load a shell, which in turn will load Python.

    Even more not so. The command "/bin/sh /usr/bin/python"
    will attempt to parse the file "/usr/bin/python" as though it were a
    shell script. That's almost certainly not what you wanted.

    To do what you describe requires the line:

    /bin/sh -c '/usr/bin/python'

    which hands the command string "/usr/bin/python" to
    /bin/sh for interpretation. Were you to do this as a cron line, the
    string: "/bin/sh -c '/usr/bin/python'" would be handed
    to /bin/sh for interpretation. That interpreter in turn then hands
    "/usr/bin/python" to /bin/sh for interpretation.

    A parent-child nested process listing (with some fake quoting tossed in
    to show the strings) would look like this:

    /bin/sh -c "/bin/sh -c '/usr/bin/python'"
    /bin/sh -c '/usr/bin/python'

    i.e. three process alive.

    > Or, in Python, you can use "socket.gethostname()", which will
    > get you the host name used for networking purposes.

    Or, on a cron line (after the time fields, omitted here):

    HOSTNAME=`hostname`; export HOSTNAME; python

    Cameron Simpson <> DoD#743

    186,282 miles per second - Not just a good idea, It's the Law!
    Cameron Simpson, Aug 18, 2008
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Horst Walter

    Java Task / Cron environment

    Horst Walter, Mar 2, 2004, in forum: Java
    Horst Walter
    Mar 4, 2004
  2. Replies:
  3. Stephen Cattaneo
    Asun Friere
    Aug 19, 2008
  4. Replies:
  5. Shawn Milochik
    Asun Friere
    Aug 19, 2008

Share This Page