2

I've a script that runs fine when I ssh to my ubuntu EC2 instance and run it (as the user ubuntu)

I want this to happen when the server boots, so I added it to cron as:

@reboot sleep 10 && /home/ubuntu/start.sh

However when cron runs it, the PATH is not the same and some commands fail because binaries are not loaded:

$ echo $PATH
/home/ubuntu/.nvm/versions/node/v4.2.6/bin:/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# in start.sh
echo "path $PATH" >> start.logs
# will log 'path /usr/bin:/bin'

I've tried to add source /home/ubuntu/.bashrc in my start.sh script since I believe that's where the PATH is built, at least partially, but that doesn't seem to change much:

# in start.sh
source /home/ubuntu/.bashrc
echo "path $PATH" >> start.logs
# will still log 'path /usr/bin:/bin'

I've also checked that Cron runs as ubuntu and not root, which seems to be the case since I edited the cron jobs being logged in as ubuntu

Is there an easy way to get cron run in the same environment I get after login to my server by ssh?

1
  • Does /home/ubuntu/start.sh have a shebang? If so, is it #!/bin/bash or #!/bin/sh? AFAIK source is not a valid synonym in the dash shell (and there are likely things in your .bashrc that it will barf on as well) Nov 5, 2016 at 22:22

3 Answers 3

2

Normally environment variables should be defined in ~/.profile, or ~/.bash_profile if this file exists your login shell is bash. So load this file from the cron job.

@reboot . ~/.profile; sleep 10 && /home/ubuntu/start.sh

~/.bashrc is for interactive customizations only, so you shouldn't load it non-interactively and it usually won't work anyway. If you have environment variables definitions in .bashrc, fix that mess first.

Another place to set environment variables is ~/.pam_environment, if you want to the variable to a constant value (you can't run shell commands in this file).

See What's the best distro/shell-agnostic way to set environment variables?, Difference between Login Shell and Non-Login Shell? and Is there a ".bashrc" equivalent file read by all shells? for more information on shell startup files.

1
  • Like such answers which get to the root of the problem i.e., fix the .bashrc mess first. Did it in right earnest! Jul 15, 2019 at 4:43
0

cron typically runs with sh not bash, these have different profiles.

try running the individual cron under bash, if you have a number of custom env vars you can alway env>/file, source /file in the cron.

1
  • thanks for the clue. I'd rather not pass manually environment variables (because I might forget some) and get cron to run with bash. I've added SHELL=/bin/bash to my cron file but that doesn't seem to change the result
    – Guig
    Nov 5, 2016 at 22:38
0

I solved my issue as:

  • run $ crontab -e, and add before all other lines SHELL=/bin/bash This will force cron to use bash. There are alternatives if you want to only do that for one command
  • my .bashrc, which was the default you get on an AWS EC2 ubuntu instance, had those lines:

.

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

so doing source /home/ubuntu/.bashrc would do nothing in the cron job. It seems to serve a purpose so I didn't removed it entirely but replaced it by:

# If not running interactively, don't do anything
if [ -z ${RUN_BASHRC+x} ]; then
  echo "might return";
else
  case $- in
      *i*) ;;
        *) return;;
  esac
fi

which let me set a flag to bypass this early return.

  • Finally, for some reasons, the PATH was still not updated correctly. I could fix it by doing:

.

ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH

I'm not 100% sure what that does :) but it at the end I've the same PATH I'd have with logging in with ssh.

So finally:

crontab:

SHELL=/bin/bash
@reboot RUN_BASHRC=1 /home/ubuntu/startup.sh >> /home/ubuntu/cron-startup.logs

~/.bashrc: the replacement above

~/start.sh:

#!/bin/bash
ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH
...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .