I wanted to run a script on a remote machine. The simple solution is this:
ssh remote1 some-script
This works until the remote script doesn't want to connect to another remote machine (remote2
) which requires interactive authentication, like tis one (remote2
is only reachable through remote1
in this case):
ssh remote1 "ssh remote2 some-script"
The solution for the problem is to use the -t
option for ssh.
ssh -t remote1 "ssh remote2 some-script"
This works, but I get probems in case I use this (where some-script
may execute further ssh commands):
ssh -t remote1 some-script
I found that some environment variables are not set which are set when I don't use the -t
option. These envrionment variables are set in scripts from /etc/profile.d
. I guess that these scripts are not run for some reason if using the -t
option, but are run if I don't use it.
What's the reason of this? Is there any way to work around it? I am using SUSE linux (version 10).
Edit: I did some additional research. I put some output lines to the following places:
- in one file in
/etc/profile.d
- in
~/.bash_profile
(file didn't exist before) - in
~/.bashrc
(file didn't exist before)
Then I checked several scenarios what output I get and in what order (the environment variable I checked is $PATH
):
ssh remote1
:profile.d
,.bashrc
,.bash_profile
.$PATH
OK.ssh -t remote1
:profile.d
,.bashrc
,.bash_profile
.$PATH
OK.ssh remote1 echo '$PATH'
: only.bashrc
.$PATH
OK.ssh -t remote1 echo '$PATH'
: no script output.$PATH
NOK.
Now I really don't understand what's going on. If I run an interactive shell, everything seems to be working fine (though I find it strange that ~/.bashrc
is included before ~/.bash_profile
). If I start a non-interactive shell without -t
, profile scripts don't seem to run but environment variables are set. If I start a non-interactive shell with -t
, then profile scrtipts are not run and environment variables are not set. Does anyone have an explanation on this?
All questions are answered in the "INVOCATION" section of the bash man page:
As you can see, interactive shells only source
.bashrc
, and often.bash_profile
would be sourced from there, which explains the order that you are seeing.Very often, these files also have a condition to only parse certain sections for interactive shells only (
[[ $- == *i* ]]
), which would explain why some parts might appear to be missing for non-interactive shells.I didn't find the reason of the problem. Maybe it's specific for the platform (SLES 10 or the variation I use). I found a workaround instead:
This forces a login shell which runs profile scripts.
The difference between
and
is also explained in the bash manpage:
In the first example,
bash
's stdin is connected to a network connection, so it runs~/.bashrc
. In the second, its stdin comes from a pseudo-terminal, so it doesn't.