Bash – Run a command in an interactive shell with ssh after sourcing .bashrc

aliasbashshellssh

I want to ssh into a remote Ubuntu computer, source my .bashrc and run a command that depends on parameters set by that .bashrc. All that in an interactive shell that doesn't close after the command is done.

What I tried until now is

ssh user@remote_computer -t 'bash -l -c "my_alias;bash"'

or just

ssh user@remote_computer -t "my_alias;bash"

This works for general commands (like ls for example) but when I try to run an alias defined in .bashrc I get an error:

bash: my_alias: command not found

But then when I write it manually again and run it, it works!

So how can I make sure the the .bashrc is sourced before the command is called?

Best Answer

The problem is that you are trying to run an alias in a non-interactive shell. When you run ssh user@computer command, command is run non-interactively.

Non interactive shells don't read aliases (from man bash):

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS below).

It works if you run it again manually because the final bash command starts an interactive shell so your aliases are now available.

As an alternative, you could launch an interactive shell (bash -i) instead of a simple login shell (bash -l) on the remote machine to run your alias:

ssh user@remote_computer -t 'bash -ic "my_alias;bash"'

This seems a very complicated approach though. You haven't explained why exactly you need to do this but consider these alternatives:

  1. Just start a normal login interactive shell on the remote machine and run the command manually:

    user@local $ ssh user@remote
    user@remote $ my_alias
    
  2. If you always want that alias to be run when you connect to this computer, edit the ~/.profile (or ~/.bash_profile, if present) of the remote computer and add this line at the end:

    my_alias
    

    Because ~/.profile is read each time a login shell is started (so, each time you connect via ssh, for example), that will cause my_alias to be run each time you connect.

    Note that by default, login shells read ~/.profile or ~/.bash_profile and ignore ~/.bashrc. Some distributions (Debian and its derivatives and Arch, for example) distributions like Ubuntu have their default ~/.profile or ~/.bash_profile files source ~/.bashrc which means that your aliases defined in ~/.bashrc will also be available in a login shell. This isn't true for all distributions, so you might have to edit your ~/.profile manually to have it source ~/.bashrc. Also note that if ~/.bash_profile exists, ~/.profile will be ignored by bash.

Related Question