1

What I need:

I am trying to change /etc/bashrc in such a way that shell could display specific text when the following ssh command is entered

ssh user@ip "whoami"

But I don't understand what exactly I should change there as I don't understand which line in this files refers to actions when the shell is non-interactive login shell.

What I tried:

Without any changes in /etc/bashrc shell returns the user name after that command, so I thought that I needed to change the value of $PS1. I tried to change it, but it did not work.

I also googled that for non-interactive non-login shells BASH_ENV is important, but in my case the shell is non-interactive login shell. So should I use $BASH_EVN as well? Should I add it to /etc/bashrc?

3
  • Can you add what the expected output is supposed to look like?
    – muru
    Commented Feb 19 at 3:55
  • The result should be like this: ``` ssh user@ip "whoami" [here shell asks for password: ...] HELLO [this is the result text that should be displayed] ```
    – Judith5230
    Commented Feb 19 at 4:42
  • ssh user@ip "whoami" will run whoami in a non-interactive non-login shell on the server. Commented Feb 19 at 7:21

1 Answer 1

1

~/.bashrc and the equivalent system-wide one if any (generally /etc/bash.bashrc) is normally not read by non-interactive invocations of bash. It is also not read by interactive login shell invocations, though that's generally considered a misfeature, so you often find the bash_profile files work around it by sourcing bashrc when interactive.

In ssh user@host 'some shell code', (and if bash happens to be the login shell of user on host), sshd on host runs bash -c 'some shell code', it's neither an interactive nor a login shell invocation.

Now the bashrc files may be sourced when bash is invoked by sshd when the bash interpreter on the system has been built with /* #define SSH_SOURCE_BASHRC */ uncommented in the config-top.h file in the source which some OSes (such as Debian) do.

If you're on such as system, then you should be able to tell if bash was invoked from ssh host 'some bash code' in the bashrc by checking that:

  • it's a non-interactive invocation of bash: [[ $- != *i* ]]
  • it's invoked as bash -c <some-code>: [[ $- = *c* ]]. When run with -c, bash is normally not interactive, so the previous check may be seen as redundant. Exception would be if bash is run as bash -ic 'some code'.
  • it's invoked over ssh: [[ -v SSH_CLIENT || -v SSH2_CLIENT ]] using the same heuristic as bash does.
  • $SHLVL is 1 (to avoid cases where bash is run again within a ssh session, though in those cases, bashrc should not be run when non-interactive, so it would only cover cases where bashrc is sourced explicitly): [[ $SHLVL = 1 ]]¹. That's still not necessarily foolproof.

So, at the top of the bashrc:

if [[ $- != *i* && $- = *c* && (-v SSH_CLIENT || -v SSH2_CLIENT) && $SHLVL = 1 ]]; then
  printf>&2 'I was most likely invoked as ssh host %q\n' "$BASH_EXECUTION_STRING"
  if [[ $BASH_EXECUTION_STRING = whoami ]]; then
    echo Something specific here
  fi
fi

¹ note that we do $SHLVL = 1 (string comparison) rather than $SHLVL -eq 1 (number comparison) as doing the latter would introduce a command injection vulnerability. That should be equivalent as we don't expect $SHLVL to contain any other representation of the number 1 such as 01, 0x1...

3
  • Wow. I always wondered about how .bashrc fit into the grand scheme of things. Never knew it isn't called in interactive invokations but duh, maybe that's why I've always seen it being invoked in the .bash_profile Commented Feb 19 at 14:07
  • 1
    It is called in interactive invocations and that's where it should be called, but bash has that quirk that is not called in ones that are login ones in addition to being interactive. Other shells don't have the problem. .profile is meant to customise your login session, .shellrc to customise the shell (for interactive use) Commented Feb 19 at 14:12
  • Stéphane Chazelas, thank you, it worked. I also found shorter alternative: adding condition if [ -z "$PS1" ] then echo "Hello" else ... turned out to be enough to solve my problem.
    – Judith5230
    Commented Feb 23 at 12:15

You must log in to answer this question.

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