4

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?

3 Answers 3

1

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:

ssh -t remote1 "/bin/bash --login -c some-script"

This forces a login shell which runs profile scripts.

0

All questions are answered in the "INVOCATION" section of the bash man page:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

When a login shell exits, bash reads and executes commands from the file ~/.bash_logout, if it exists.

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.

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.

3
  • This still does not explain the difference between calling ssh with and without -t. I also checked the appropriate profile.d file and /etc/profile. In profile.d there are no special checks for setting $PATH. In /etc/profile the only check is that $PROFILEREAD is empty, wich is set at the end of that script. I checked, this variable is set when I run ssh without -t, but not if I run it with -t.
    – petersohn
    Oct 24, 2012 at 12:02
  • The only difference between ssh server command and ssh -t server command is the presence of a tty. Have you checked if any of the files in /etc/profile.d are doing such checks? grep for tty or TERM and see what that brings about.
    – chutz
    Oct 24, 2012 at 15:46
  • As I said, the files in /etc/profile.d has no such conditions. I also checked /etc/profile, again not containing such conditions. It is possible that it is a platform specific problem on this system, but I can't find the cause.
    – petersohn
    Oct 25, 2012 at 13:16
0

The difference between

ssh remote1 echo '$PATH'

and

ssh -t remote1 echo '$PATH'

is also explained in the bash manpage:

Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by the remote shell daemon, usually rshd, or the secure shell daemon sshd. If bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc [I assume that should read /etc/bash.bashrc] and ~/.bashrc, if these files exist and are readable.

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.

You must log in to answer this question.

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