4

I'm wondering how to load bashrc variables in an upstart script and run (node.js in that case server).

What is the best way to do it?

I tried this:

exec sudo -u someuser $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1

and this

exec start-stop-daemon --start -c someuser --exec $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1

But in the first option the node app can't read the http_proxy variable (which is defined in /etc/bash.bashrc). In the second one it can't read config files (the node app is installed in the /opt folder)

drs
  • 5,453

3 Answers3

5

/etc/bash.bashrc is read by interactive shells when they start up. It is a place for settings for interactive use, such as completion setup, prompts, etc. Do not set environment variables there. See Is there a ".bashrc" equivalent file read by all shells? Good places for system-wide environment variables are /etc/environment and /etc/profile (and files in /etc/profile.d).

The normal Upstart way to set environment variables is in the job file itself. Upstart doesn't read /etc/environment, but you can load environment variables from a file in the job script:

script
. /etc/environment
exec start-stop-daemon …
end script
  • I like this idea most. It's generally a bad idea to have any additional layers of processes between upstart and the daemon you start. Because who know how this seven-layer salad of sudo, start-stop-daemon, bash, and custom scripts will react to signals, for example? – Ivan Anishchuk Sep 09 '15 at 18:03
1

You can force bash to read /etc/bash.bashrc and ~/.bashrc (without the other side effects of using bash -i) by tricking it into thinking it's invoked over ssh:

sudo -Hu someuser env SSH_CLIENT=1 SHLVL=0 \
  "NODE_PATH=$NODE_PATH" "FULL_PATH=$FULL_PATH" \
  "FILE_NAME=$FILE_NAME" "PROGRAM_NAME=$PROGRAM_NAME" bash -c '
  "$NODE_PATH" "$FULL_PATH/$FILE_NAME" >> "/var/log/$PROGRAM_NAME.sys.log" 2>&1'

sudo usually resets the environment, so you need to pass those that way. You want -H (or -i though -i would cause the reading of the profile files) so that HOME is set (for the location of ~/.bashrc at least).

0

You can force bash to be executed as interactive shell. Try this command:

sudo -iu someuser /bin/bash -i -c '$NODE_PATH $FULL_PATH/$FILE_NAME \
>> /var/log/$PROGRAM_NAME.sys.log 2>&1'

Now, before your command is executed, ~/.bashrc and /etc/bash.bashrc are sourced by bash. It's the same behavior as when you open a terminal.

chaos
  • 48,171
  • Thank you for your comment. But it seems to doing nothing. Am I doing something wrong? – user1760395 Aug 12 '14 at 14:38
  • @user1760395, it likely created a file called /var/log/.sys.log that contains a complaint about / being a directory unless those variables are defined in the .bashrc. See the note about environment variables in my answer. – Stéphane Chazelas Aug 12 '14 at 15:03