1

I need to run an ssh sudo command.

command is as follows:

ssh -i keyfile [email protected]  '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?

1
  • ssh -i keyfile [email protected] "ubuntu" is userA on target machine. Your original answer was spot on. I was just unclear about option of creating a special_env file or using the ~./bashrc as is Commented Jan 9, 2021 at 2:01

1 Answer 1

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 [email protected]  '. ~/.special_env; sh -v /opt/dir/script'
8
  • I think the simplest thing to do would be to move them vars defined in ~/.bashrc to another file namely ~/.special_env. and then load those before the script is run. Is that what you are implying? Agree? Commented Jan 9, 2021 at 0:15
  • @reza Well, it's a matter of opinion if rearranging ~/.bashrc is not simpler. Pick a method that works best for you. If I were you I would start with modifying ~/.bashrc only. If I didn't encounter any problems then there would be little point in creating ~/.special_env and sourcing manually while ~/.bashrc does the job automatically. Commented Jan 9, 2021 at 0:24
  • either create a new env file or source ~/.bashrc? So 'source ~/.bashrc ; sh -v /opt/dir/script'. Do I have that correct? Commented Jan 9, 2021 at 0:53
  • @reza Sourcing ~/.bashrc happens automatically. If there's code that returns in a non-interactive shell then it will return even if you explicitly source the file in a non-interactive shell. Is there such code in your ~/.bashrc? Commented Jan 9, 2021 at 0:59
  • I tried the above suggestion of ssh -i keyfile [email protected] '. ~/.special_env; sh -v /opt/dir/script' and the application run from the bash script does not see the env variables defined and it is not propagated Commented Jan 12, 2021 at 16:42

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.