I'm experiencing a strange behavior when I try to execute one of my scripts on a remote machine via ssh
.
I prepend the path to my scripts dir to $PATH
in my .profile. But when I run ssh kalle@Raspi foo
, I get "command not found".
ssh kalle@Raspi 'echo $PATH'
gives the default value, and with variables I set and export in .profile, the output is empty.
I put an echo foo
in .profile, and of course, it is printed.
Then I put set -vx
in the first line and the order of the printed lines is weird; e. g. "foo" is printed before "+echo foo".
Can anyone figure out what's going on?
EDIT:
When I do ssh kalle@Raspi 'bash -lc "echo \$PATH"'
, I get my full path.
EDIT 2:
I'm sorry for the confusion, I was very tired when I wanted to run my remote script and now my memory was wrong, but I remember now what I did.
I tried with bash -lc
after it didn't work with the mere command, but I missed the backslash! So I had ssh kalle@Raspi 'bash -lc "echo $PATH"'
and as always when you give a command string to another command, the shell performs its various expansions on that command string.
So after quote removal, we have bash -lc "echo $PATH"
which is passed to ssh
as a single argument and executed on the remote machine, where the shell performs parameter substitution, i. e. $PATH
is replaced by the default path before it is passed to bash -lc
, making the latter useless.
And then I was stupid enough to forget that I was using bash -lc
, so I thought ssh kalle@Raspi foo
would cause .profile
to be read because I saw the output of my echo
command I had put in my .profile
.
What a shame. I must have been really tired because when I wrote this question, it was absolutely natural to me that I have to protect the variable with a backslash; I didn't even have to think about it. But I still didn't realise what I realised now.
So the behavior is pretty clear and absolutely normal, but the problem remains.
I can use bash -lc
as a workaround which – depending on the situation – can be a hassle with quoting and escaping, or I can put . .profile
before the actual command.
Does anybody know a solution that is more elegant? Something I can adjust on the server so I can just use ssh kalle@Raspi foo
?
-l
option to Bash, like this:ssh kalle@Raspi 'bash -lc "echo \$PATH"'
. Alternatively, you can move your path modifications to the .bashrc file and make sure that your .bash_profile file sources your .bashrc file. – kuspia Apr 04 '23 at 07:13.profile
is NOT executed. I just tested it. – Christoph Apr 04 '23 at 15:43.bashrc
is read byssh user@host 'foo bar'
(Bash startup files / Invoked by remote shell daemon) – ilkkachu Apr 04 '23 at 17:22[ -z "$PS1" ] && return
or equivalent, anything that isn't at the very beginning of the file will not be read. This is why it's confusing if you add sayecho foo
to your~/.bashrc
and thenssh localhost hostname
, you just get the host name and nofoo
. – terdon Apr 04 '23 at 17:35.bashrc
... (Or rather, started from a clean file and never bothered to add it. And yes, I've learned to protect any output from there withif tty -s
or so.) Anyway, the fact that Bash does read it in that case is somewhat odd, IMO, it doesn't seem to fit with logic it otherwise has there. – ilkkachu Apr 04 '23 at 19:35