1

I need to run an ssh sudo command.

command is as follows:

ssh -i keyfile ubuntu@10.65.21.253  'sh -v /opt/dir/script'

the script contains the following:

sudo -E node some.js

the reason I use the -E argument is that the command is being run by userA AND the process being started needs to load definitions from

/user/userA/.bashrc

the above command does NOT load the variables defined in /user/userA/.bashrc

it is running really as though the -E is not doing anything. i.e all the variables show as undefined.

If I log in to the remote machine interactively as userA and run the same command, namely,

sudo -E node some.js

the variables are loaded correctly and I see the expected behavior.

Can anyone see what I need to do differently?

reza
  • 385

1 Answers1

2

You're expecting the shell to source ~/.bashrc, so I assume the shell is Bash.

Twist number 1: SSH server passes the shell code to a non-interactive shell. Non-interactive Bash does not read ~/.bashrc.

Twist number 2: Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by a SSH server. If bash determines it is being run in this fashion, it does read and execute commands from ~/.bashrc.

Twist number 3: In many distros (including Ubuntu) the default (skeletal) ~/.bashrc starts with code that returns if the shell is non-interactive. In effect the rest of the file is not sourced.

I guess in your case the relevant environment variables are defined after this piece of code. The code may look like this:

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

A straightforward solution is to move the assignments so they are before this code. If you'd like to move commands that do more (e.g. echo something, run something) then be very careful because you may break remote file transfers. Read Why does bashrc check whether the current shell is interactive? If it's about variables only then you should be safe.

In general the environment should be defined in ~/.profile rather than in ~/.bashrc, but if you moved the assignments to ~/.profile then you would experience this: ~/.profile is not loaded when using SSH. It's not unreasonable to have them in ~/.bashrc then.

Alternatively you can place them in a separate file, e.g. ~/.special_env, and source the file from ~/.bashrc or ~/.profile or whatever. The advantage is you can source the file on demand regardless of quirks and twists:

ssh -i keyfile ubuntu@10.65.21.253  '. ~/.special_env; sh -v /opt/dir/script'