Send Aliases over SSH connections

Bash reads aliases from a file only; however, this file does not have to reside on the server you are connecting to. With OpenSSH, we have to ability to send environment variables that the server allows.

On Debian/Ubuntu systems, the default accept environment variables are:
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

On CentOS/Fedora systems, the default accept environment variables are:
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

If you remote into a mixed environment of servers – whether they be Debian, Ubuntu, or CentOS, you will need to find a common AcceptEnv variable. Since Debian and Ubuntu allow LC_* (everything with the prefix LC_), we are limited to forwarding our aliases over one of CentOS’s variables. For me, it was easy to decide on a variable to overwrite – LC_PAPER. I hardly print anything and I especially do not print on remote servers.

In order to send your aliases into a remote server, you have to set up your environment first.

In ~/.ssh/config, you need a line that sends the environment variable of your choice. These two lines denote that for every host, we will send the environment variable.

Host *
     SendEnv LC_PAPER

Next, we will have to set an alias file we want to transfer. For my test, I create ~/.bash_aliases_xfer and had the contents of:

# .bash_aliases_xfer
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
alias lollypop="echo lollypop"
alias lolp="lollypop"
#My servers display useful information in the motd.
[ ! -z "$TERM" -a -r /etc/motd ] && cat /etc/motd

Next, we have to craft our ssh command:

LC_PAPER=$(cat ~/.bash_aliases_xfer; exec 3<&-) \
ssh -t user@remote \
    'exec bash --rcfile /dev/fd/3 3< <(printf %s "$LC_PAPER")'

The first line defines the environment variable – an output of our local file and places that information in file descriptor 3. The second line is where we actually connect to the server. The third line is the command executed on the remote server: cleanly print the contents of our environment variable, put that information in file descriptor 3, and reload bash with that file as the only configuration file.

To make the process easier, I have place the following function in my .bashrc. Since the function has $@ variable, I can use it as a replacement to ssh and I can pass any needed ssh switches to my new function.

function ssha() {
LC_BASHRC=$(cat ~/.bash_aliases_xfer; exec 3<&-) ssh -t "$@" 'exec bash --rcfile /dev/fd/3 3< <(printf %s "$LC_BASHRC")';
}

After I reload my bashrc ( source ~/.bashrc ), I can then pass my aliases into my new ssh session: ssha user@remote -i ~/.ssh/remote_id -X.