38

Edited to reflect the problem I really wanted to solve:

I need to set up my ruby environment so I can deploy via Capistrano.

export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init -)"

I put these in ~deploy/.profile, but when I ssh in, they aren't being run. Ideas?

I'm running Ubuntu 12.04.


The original question was:

When I ssh into another account at localhost, it doesn't load my .profile. How can I force ssh to load it? I'm running Ubuntu 12.04.

Charles R
  • 511
  • 1
  • 4
  • 6

8 Answers8

21

You may explicitly specify that you want to start an interactive login shell:

 ssh user@host bash --login -i 

The "role" of ~/.profile (or ~./bash_profile) and .bashrc for ssh have some other files, (see man ssh for details):

~/.ssh/environment

Contains additional definitions for environment variables; see ENVIRONMENT, above.

~/.ssh/rc

Commands in this file are executed by ssh when the user logs in, just before the user's shell (or command) is started. See the sshd(8) manual page for more information.

12

.profile is only loaded for login shells, which an ssh session is not (by default). If you want something to run on startup for all interactive shells, put it in .bashrc instead (or .zshrc or whatever your shell uses).

Also, if you just want to log into another account on the local machine, ssh is probably overkill. You might want to use su or something instead.

qmega
  • 3,128
  • 1
  • 15
  • 10
  • 11
    It seems `.bashrc` is not loaded either. – kenorb Oct 02 '14 at 20:25
  • This is incorrect. It **is** a login shell. From the man page: "If command is specified, it is executed on the remote host instead of a login shell." – mkj Jul 23 '15 at 11:23
  • ~/.zshenv works for me. http://unix.stackexchange.com/questions/4921/sh-startup-files-over-ssh/ – user91155 May 03 '16 at 03:22
  • 2
    When ssh is given a command to run, it defaults to *not* allocate a tty and then the shell is not “interactive” either. – Jan Hudec Sep 25 '19 at 12:39
7

You probably have a ~/.bash_profile, which overrides ~/.profile.

user541686
  • 23,663
  • 46
  • 140
  • 214
  • Simplest explanation. Installed some package, and colors disappeared. Turns out a rogue `.bash_profile` appeared and stole my colors – Aviad P. Aug 05 '23 at 07:41
7

Using bash should result in reading ~/.bashrc. The following might help with ksh and sh (bash in sh mode), or when your ~/.bashrc is not executed during login.

The sshd consults ~/.ssh/environment (check sshd_config(5) for permissions) and ~/.ssh/sshrc or ~/.ssh/rc. This gives the possibility to setup ENV=~/.profile or BASH_ENV=~/.profile and SSH_LOGIN=Y

In ~/.profile I've the following layout (Replace ENV with BASH_ENV when using bash):


if [[ -n $SSH_LOGIN || -z $ENV ]]; then
     # Put here login initialization code
     unset SSH_LOGIN
     ENV=~/.profile
fi
 # Put here code thats get executed with each ksh/sh invocation
eremmel
  • 171
  • 1
  • 4
1

Bash reads ~/.profile only when it is a login shell and ~/.bash.bashrc only if it has a terminal, neither of which is true by default when invoking a command with ssh. However, there are several other options to set environment, on the server, all unfortunately depending on the system setup:

  • Zsh reads ~/.zshenv even in this case; there is no corresponding config file for bash though.
  • If the PermitUserEnvironment option is on in /etc/sshd_config, ssh will read ~/.ssh/environment. Unfortunately this option defaults to off.
  • If the pam_env.so is called with user_readenv=1 in /etc/pam.d/sshd, it will read ~/.pam_environment. While it is not default of the module, it is called that way at least in Ubuntu.
  • If all else fails, you can put a command= directive in the authorized keys file calling a wrapper script that sets the environment and executes the $SSH_ORIGINAL_COMMAND at the end (I the command is one for shell, so eval is appropriate here, but I am not sure).
Jan Hudec
  • 1,015
  • 7
  • 20
0

If you have root access then you can put environment variables in /etc/environment. That way, they are set no matter what shell or login type you are using.

Björn Lindqvist
  • 349
  • 1
  • 6
  • 15
0
ssh localhost 'echo $MyEnv'

ssh with command will try to source $BASH_ENV according to gnu bash manual because it is a non-interactive shell I think

https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files

hx_hxl
  • 1
  • 1
    Welcome to SuperUser! How is this better than the accepted answer? – DarkDiamond Jun 17 '22 at 06:42
  • @DarkDiamond This particular answer might not be much help, but note that there is no accepted answer. So this may in fact be better than the empty set. – Mark Adler Aug 25 '22 at 00:18
0

From the question it isn't clear if you're ssh-ing into the deploy user's account and running commands:

ssh deploy@myhost

... or if you're using ssh to run a command as the deploy user:

ssh deploy@myhost my-command-to-run

If I am logged into a host and:

earl@myhost:~$ echo $PATH
/home/earl/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

It shows /home/earl/bin at the beginning of my PATH because I set it in my ~/.profile file.

If I ssh to another user on the same machine:

earl@myhost:~$ ssh deploy@myhost
deploy@myhost:~$ echo $PATH
/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

The login is now using the PATH setting for the deploy user because I'm using an interactive ssh login shell. It's getting the PATH setting from deploy's ~/.profile file, which doesn't contain /home/earl/bin.

However, if I just typed:

earl@myhost:~$ ssh deploy@myhost ./run-commands.sh

ssh is going to ssh into the deploy user's account on the same host and run the deploy user's ./run-commands.sh script, but ssh will not be using a login shell and none of the environment settings in the deploy user's ~/.profile or ~/.bashrc or ~/.bash_profile files will be executed because ssh is just running a command, it isn't starting a shell.

If you're trying to use ssh interactively, and .profile isn't getting run, you probably set the shell for deploy to a shell that doesn't exist or a shell that doesn't use .profile files. Try:

earl@myhost:~$ ssh deploy@myhost
deploy@myhost:~$ ps -p $$

... to find out what shell the deploy user is using.

If you're trying to use ssh to run a command, create a run-commands.sh shell script, add:

source ~/.profile

... to the beginning of the shell script, followed by the commands you want to run, and then ssh deploy@myhost ./run-commands.sh should work.

Earl Ruby
  • 321
  • 2
  • 3