10

On a particular host, when I ssh into the machine and enter echo $PATH I get

/home/wxy/bin64:/home/wxy/bin:/usr/kerberos/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin

and if I execute ssh host 'echo $PATH' I see this:

/usr/local/bin:/bin:/usr/bin

Why is this discrepancy?

Also what can I do if I wanted to see the former result using the latter command?

3 Answers 3

14

In the first scenario you're logging into the system so you're executing what's called a login type of connection. A login sources the scripts in $HOME/.bashrc and $HOME/.bash_profile if you're login shell is Bash. These 2 scripts in turn typically source the files /etc/bashrc and the files under /etc/profile.d/*.sh.

For the second scenario you're only sourcing the file $HOME/.bashrc. This type of login is called interactive.

You can read more about these in the INVOCATION section of the bash man page.

To change this behavior you can include the $HOME/.bashrc_profile as part of the interactive execution to get the desired behavior:

$ ssh user@remotehost '. $HOME/.bash_profile; echo $PATH'

-or-

$ ssh user@remotehost 'source $HOME/.bash_profile; echo $PATH'

References

3
  • And is there any way I can have the sourcing from the login type while having an interactive connection? Jun 17, 2013 at 18:31
  • @ProgrammingNoob - see updates.
    – slm
    Jun 17, 2013 at 18:40
  • 1
    /etc/bashrc is was very useful to me as it loads environment vars (no need to source ~/.bash_profile) which need to be visible to some scripts I needed to run via ssh.
    – prayagupa
    Jun 29, 2017 at 9:38
3

Session initialization files are weird, for hysterical historical reasons.

A long time ago, you logged in on the console, period. When you logged in, you got a shell, and the shell would load some initialization file. For Bourne-style shells, there are two initialization files: /etc/profile (for all users) and ~/.profile (for each user). The initialization file can set environment variables such as PATH, load applications that you want to run in every session (e.g. a mail indicator), etc. If a shell isn't a login shell, it doesn't need to start anything or set environment variables, so there's no need to run any initialization file. Surely there isn't…

Actually, shells gradually gained interactive features, so there's a need for an initialization file for interactive shells. Ksh has ~/.kshrc, bash has ~/.bashrc, zsh has ~/.zshrc.

Remote interactive logins run /etc/profile and ~/.profile. But these are not suitable to non-interactive logins because they may start non-interactive programs. Unfortunately, no standard has emerged for an initialization file for non-interactive logins.

You can run /etc/profile and ~/.profile manually if you're sure they won't produce any output or start any program, just set environment variables.

ssh foo '. /etc/profile; . ~/.profile; somecommand'

If you have parts in your .profile that only make sense in an interactive session, you can put them inside a conditional instruction.

## (in ~/.profile)
case $- in
  *i*) # the shell is interactive
    newmail;;
esac

If your login shell is bash, you can take advantage of a quirk: the initialization file ~/.bashrc is read by interactive shells, and also by non-interactive shells whose parent process is called rshd or sshd. Other shells don't have this quirk.

## (in ~/.bashrc)
case $- in
  *i*) # interactive shell: set prompt, completion settings, key bindings, etc.
    …;;
  *) # non-interactive shell: our parent must be rshd or sshd
    . ~/.profile;;
esac
3
  • Are they run or are they sourced?
    – Adrian
    Nov 20, 2022 at 3:08
  • 1
    @Adrian They're all sourced. Otherwise they couldn't perform most of their job (set environment variables, set shell options, define aliases and functions, etc.). Nov 20, 2022 at 11:12
  • Yeah. Thought so. Was confused by your statements "...run /etc/profile and ~/.profile..."
    – Adrian
    Nov 20, 2022 at 13:39
0

if you are using bash then check /etc/profile on the host that you are not able to get your expected output. Please note that bash 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.

You must log in to answer this question.

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