40

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
  • 531

8 Answers8

23

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.

13

.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,266
7

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

user541686
  • 23,629
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

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,025
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.

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
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
  • 318