How do I set $PATH such that `ssh user@host command` works?
Solution 1
As grawity said, ~/.bashrc is what you want, since it is sourced by non-interactive non-login shells.
I expect the problem you're having has to do with the default Ubuntu ~/.bashrc file. It usually starts with something like this:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
You want to put anything for non-interactive shells before this line.
Solution 2
Do you have an ~/.bash_login
or ~/.bash_profile
?
Bash in interactive mode checks for these files, and uses the first existing one, in this order:
~/.bash_profile
~/.bash_login
~/.profile
So if you have an ~/.bash_profile
, then whatever changes you do to ~/.profile
will be left unseen.
Bash in non-interactive mode sometimes reads the file ~/.bashrc
(which is also often source'd from the interactive scripts.) By "sometimes" I mean that it is distribution-dependent: quite oddly, there is a compile-time option for enabling this. Debian enables the ~/.bashrc
reading, while e.g. Arch does not.
ssh
seems to be using the non-interactive mode, so ~/.bashrc
should be enough. When having problems like this, I usually add a few echo's to see what files are being run.
Solution 3
ssh documentation says:
If command is specified, it is executed on the remote host instead of a login shell.
which is why adding to the bashrc files doesn't work. you do however have the following options:
If the
PermitUserEnvironment
option is set in the sshd config, you can add your PATH setting to~/.ssh/environment
ssh remotemachine 'bash -l -c "somecommand"'
Solution 4
You can always say:
ssh remotemachine 'export PATH=wedontneedastinkingpath; echo $PATH'
Solution 5
In addition to @signpolyma answer, you will have to add your export before these lines
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Denver Gingerich
Updated on July 08, 2022Comments
-
Denver Gingerich almost 2 years
I can't seem to set a new $PATH such that it is used when executing commands via
ssh user@host command
. I have tried addingexport PATH=$PATH:$HOME/new_path
to ~/.bashrc and ~/.profile on the remote machine, but executingssh user@host "echo \$PATH"
shows that the change has not been picked up (it shows /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games). The remote machine is running Ubuntu 8.04.I'm sure I could hack it into /etc/profile, but that's not a clean solution and it only works when one has root access.
-
Denver Gingerich almost 15 years1. It's not set in my sshd config and
man sshd_config
says it's off by default so it's unlikely this solution would work for most people. 2. This would work, but I can't easily modify the command sent to ssh (see the second comment on my question). -
Denver Gingerich almost 15 yearsYep, I moved the
export PATH=$PATH:$HOME/new_path
above that line and it worked. Thanks! -
Jess about 11 yearsAdding the echos helped... but I'm still chasing down a way to execute 'ssh -X remotemachine "xterm"' and have the full system / user path from /etc/profile and ~/home/username/.bash_profile. If I source both file in the command, it works.. but its ugly : ).
-
basin about 11 years.bashrc is unreliable. man bash: "Bash attempts to determine when it is being run with its standard input connected to a network connection". This works on RHEL, but not on Archlinux. I had to edit /etc/environment to change the default PATH
-
nknight about 11 yearsHow do you know that "Bash in non-interactive mode reads the file
~/.bashrc
"? I do not see this statement in the manpage. Thanks -
nknight about 11 yearsIf you want a non-interactive non-login shell to source
~/.bashrc
, it seems that you need to additionally set the environment variableBASH_ENV
; see superuser.com/a/585699/100843 . For non-interactive login shells, you'd probably have to modify one of the three startup scripts you mentioned. -
math about 10 yearsFor ZSH the non-interactive file is:
.zshenv
-
Ronny Andersson over 7 yearsThis solution does not need any change on the remote machine, which is a good thing.
-
Ernie S over 7 yearsI actually just commented out these lines altogether - found in ~/.bashrc in Ubuntu 16.04 LTS desktop. No everything works. Also set PermitUserEnvironment to yes.
-
JoL about 7 years@math
.zshenv
is always sourced; it doesn't matter if it's interactive or not. -
not2savvy about 7 years1. Does not work as expected, because in ~/.ssh/environment, you cannot add pathes to PATH, because $PATH will not be resolved.
-
Mike over 5 yearsYou should add mention of
.zshenv
for zsh users, it took me quite a while to find it in the comments on other answers -
Doomd over 3 yearson MacOS Catalina, I had to put a "zshenv" file at /etc/zshenv (with my export paths).
-
lindes over 2 years@Doomd: did ~/.zshenv not work for you? It worked for me... And yes, this answer would benefit from being edited to include information for various other shells, as well (zsh, fish, ...)