52

I am trying to execute a command remotely over ssh, example:

ssh <user>@<host> <command>

The command which needs to be executed is an alias, which is defined in .bashrc, e.g.

alias ll='ls -al'

So what in the end the following command should get executed:

ssh user@host "ll"

I already found out that .bashrc only gets sourced with interactive shell, so in .bash_login I put:

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

and I also tried to define the alias directly in .bash_login.

I also tried to put the alias definition / sourcing of .bashrc in .bash_profile and also in .ssh/rc. But nothing of this works. Note that I am not able to change how the ssh command is invoked since this is a part of some binary installation script. The only thing I can modify is the environment. Is there any other possibility to get this alias sourced when the ssh command is executed? Is there some ssh configuration which has to be adapted?

tshepang
  • 12,111
  • 21
  • 91
  • 136
blackicecube
  • 1,393
  • 5
  • 15
  • 15
  • Which machine are these files (.bashrc, etc.) on? The machine you're ssh-ing to, or the one you're ssh-ing from? – Laurence Gonsalves Jul 29 '09 at 06:49
  • The files are on the machine I am ssh-ing to – blackicecube Jul 29 '09 at 06:56
  • 1
    I also already checked the /etc/passwd for my user. It has /usr/bin/bash defined. – blackicecube Jul 29 '09 at 06:57
  • Have you tried `.bash_profile`? That's where `.bashrc` gets sourced in my machines. – drrlvn Jul 29 '09 at 07:46
  • Yes, I also tried .bash_profile and .profile and it didn't work either. – blackicecube Jul 29 '09 at 07:48
  • Is `UseLogin` set to `Yes` in your `/etc/ssh/sshd_config`? It should be set to `No` as `bash` sources `.bash_profile` only in an interactive non-login shell. – drrlvn Jul 29 '09 at 08:10
  • That's a horrible design flaw in the program. I tried both `ssh $HOST 'alias ll="ls -l"; ll'` and `ssh -t $HOST 'll'` with no luck. There may be no way around this – bradlis7 Apr 22 '10 at 19:04
  • @reinierpost No, the problem of aliases not working is distinct. Even if you source `.bashrc`, a non-interactive shell will not expand aliases. The title should perhaps be more specific that this is the problem here, though. – tripleee Aug 30 '16 at 09:46

5 Answers5

42

From the man pages of bash:

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt

There are a couple ways to do this, but the simplest is to just add the following line to your .bashrc file:

shopt -s expand_aliases
tshepang
  • 12,111
  • 21
  • 91
  • 136
Joey Mazzarelli
  • 451
  • 4
  • 5
  • I upvoted you, but you should explain what it does. – bradlis7 Apr 22 '10 at 19:11
  • 1
    As explained elsewhere here, the shell is not in interactive mode. This enables the option of expanding the aliases. From the docs: If set, aliases are expanded as described above under ALIASES. This option is enabled by default for interactive shells. – Joey Mazzarelli Apr 22 '10 at 20:21
  • Yeah, I found it, I was just suggesting that you add it to your comment. I tried doing that command in `ssh $HOST 'shopt -s expand_aliases; ll'`, but that didn't work. It probably works if put it in .bashrc, but I didn't try it. – bradlis7 Apr 22 '10 at 20:27
  • 2
    Oh, ok. If you don't want to change your environment on the destination machine, there are a couple other things you can try: `ssh user@host "bash -ic ll"` works for me by running the command "interactively", and the man pages also talk about setting shopt options with a `-O` flag to bash. – Joey Mazzarelli Apr 23 '10 at 02:09
  • @bradlis7 Your attempt fails because bash expands aliases when it reads the line (which is before "shopt -s expand_aliases" is executed). For more details, see [this answer](http://stackoverflow.com/a/2502451/436168). – Boris Bukh Jan 19 '16 at 00:59
  • `setopt aliases` for zsh is enough? I find it doesn't work. Is the only solution below answer for zsh `ssh user@host "bash -ic ll` ? – dza Jun 02 '16 at 11:44
33

Instead of:

ssh user@host "bash -c ll"

try:

ssh user@host "bash -ic ll"

to force bash to use an "interactive shell".

Annika Backstrom
  • 13,937
  • 6
  • 46
  • 52
Fred Stluka
  • 331
  • 3
  • 2
10

EDIT:

As pointed out here about non-interactive shells..


 # If not running interactively, don't do anything
[ -z "$PS1" ] && return
 # execution returns after this line

Now, for every alias in your bashrc file say i have:


alias ll="ls -l"
alias cls="clear;ls" 

Create a file named after that alias say for ll:

user@host$ vi ssh_aliases/ll
#inside ll,write
ls -l
user@host$ chmod a+x ll

Now edit .bashrc to include:


 # If not running interactively, don't do anything
[ -z "$PS1" ] && export $PATH=$PATH:~/ssh_aliases

This does the job.. although I am not sure if it is the best way to do so
EDIT(2)
You only need to do this for aliases, other commands in bashrc will be executed as pointed out by David "you must have executable for ssh to run commands".

Community
  • 1
  • 1
sud03r
  • 19,109
  • 16
  • 77
  • 96
  • Thanks for your suggestion. The aliases invoked by the installation script are defined in a custom bashrc lying somewhere in the installation directory, In that custom bashrc besides aliases there are also lots of export of variables defined. So with your solution I would need to create a file for each alias/export? – blackicecube Jul 29 '09 at 07:44
  • I just tried it, unfortunately it still doesn't work. I am not sure but it seems like .bashrc is not sourced when invoking ssh. – blackicecube Jul 29 '09 at 08:25
  • try some echo statement before "# If not running interactively, don't do anything" line and invoke first form commandline like: ssh user@machine to test whether it works or not. It works on my machine although – sud03r Jul 29 '09 at 08:33
  • @sud03r Does it work for you? I tried it without success. Are you sure that you've accepted a `CORRECT` answer? – stanleyxu2005 Mar 20 '14 at 16:58
  • @stanleyxu2005 the idea behind this is to create a binary file for every alias on the remote computer and then run it remotely using ssh. The only problem i see here is the .bashrc you are editing is not sourced, and the command is not available to execute. In such a case, you have to figure out the appropriate .bashrc (correct user) and edit that one. – sud03r Mar 24 '14 at 12:26
  • Thanks. After faking a non-empty value for PS1, I was able to `source .bashrc`... :) – anishsane Aug 24 '15 at 09:58
-1

an alternative to alias that will be visible in all script is EXPORT & EXECUTE VARIABLE

# shortcut to set enviroment to insensitive case
export go_I="shopt -s nocasematch"

Now in any script you can use

#!/bin/bash $go_I # go Insensitive [[ a == A ]] # evaluates TRUE ( $? == 0) $go_C # maibe want to go back to casesensitive

it's useful to place all shortcuts/aliases in /path/to/my_commands and edit /etc/bash.bashrc

source /path/to/my_commands

bortunac
  • 4,642
  • 1
  • 32
  • 21
-3

Open file ~/.bash_profile. If this file does not exist create one in the home directory and add the below line

source = $HOME/.bashrc

exit your ssh and login agian and you should get the .bashrc settings working for you.