Why does this bash script give an error on Ubuntu but not OSX

06
2014-04
  • codecowboy
    #!/usr/bin/env sh
    export $NODE_CONFIG_DIR=/Users/full/path/to/script/config
    cd /Users/full/path/to/script
    /usr/local/bin/node main
    

    The script runs locally on OSX (if I adjust the paths for the local environment) but on Ubuntu I get:

    ./mtf_runner.sh: 2: export: : bad variable name
    

    I want to run the script using cron and need to set the NODE_CONFIG_DIR environment variable

    Additionally, although the command runs in cron on OSX (10.8.5), I do get the following sent to my local mail:

    line 2: export: `=/Users/myname/Node/Development/tennistracker/config': not a valid identifier
    

    I've read that this could be caused by a space around = but there is definitely no space

  • Answers
  • user2313067

    This is caused by the fact that when setting a variable, you should not prefix it with $. Here, the $NODE_CONFIG_DIR is expanded into nothing (as it is unset) before running the line, which makes you run export =/Users/full/path/to/script/config. The script should be

    #!/usr/bin/env sh
    export NODE_CONFIG_DIR=/Users/full/path/to/script/config
    cd /Users/full/path/to/script
    /usr/local/bin/node main
    

  • Related Question

    ubuntu - Why is bash rsync script not writing anything to file?
  • user19496

    Ubuntu 9.10

    crontab -l

    0 1 * * * /root/cron/rsync-93.193.99.111 &> /root/cron/rsync-93.193.99.111.log
    0 3 * * * tail -100 /root/cron/rsync-93.193.99.111.log | msmtp [email protected]

    ls -l /root/cron/rsync-93.193.99.111.log

    -rw-r--r-- root root /root/cron/rsync-93.193.99.111.log

    The rsync-93.193.99.111.log file displays zero size in Nautilus.
    I get an email, but it's empty.
    Running tail -100, also shows emtpty output, so the email is correct.

    Why is the bash rsync script not writing anything to the file ?


  • Related Answers
  • Dennis Williamson

    I believe it's because &> is not supported in sh which is the shell that cron uses. Use the explicit form:

    0 1 * * * /root/cron/rsync-93.193.99.111 > /root/cron/rsync-93.193.99.111.log 2>&1
    

    Also, you can do sudo crontab -e instead of doing sudo su then crontab -e.

  • Gilles

    I concur with Dennis's assessment of your problem. But I have a couple of other points to mention.

    Most importantly, don't do this:

    0 1 * * * some command
    0 3 * * * some other command that should run after the first one
    

    What if the first command takes more or less than two hours? To make sure that the second command runs when the first finished, put them on a single line:

    0 1 * * * /root/cron/rsync-93.193.99.111 >/root/cron/rsync-93.193.99.111.log 2>&1; tail -100 /root/cron/rsync-93.193.99.111.log | msmtp [email protected]
    

    Also, you might want to take advantage of cron's automatic mailing of errors. (This assumes your system is set up properly for mail, which may not be the case if you have to run msmtp rather than mail.)

    MAIL=[email protected]
    0 1 * * * /root/cron/rsync-93.193.99.111 2>&1 | tee /root/cron/rsync-93.193.99.111.log | tail -n 100