Skip to content

Instantly share code, notes, and snippets.

@jordangarrison
Last active April 4, 2023 01:48
Show Gist options
  • Save jordangarrison/181f7378bb5053cdac7521dec28a2dc1 to your computer and use it in GitHub Desktop.
Save jordangarrison/181f7378bb5053cdac7521dec28a2dc1 to your computer and use it in GitHub Desktop.
Bring your dotfiles with you over ssh with sshrc
# Save this file as $HOME/.sshrc
# This will take your vimrc in your .sshrc and use it for vim as
# well as append any scripts in your .sshrc.d into your path on login
echo "Hi $USER!"
echo "You are on host $(hostname -f)"
# use sshrc .vimrc instead of system
export VIMINIT="let \$MYVIMRC='$SSHHOME/.sshrc.d/.vimrc' | source \$MYVIMRC"
# Path edits
# Add the $SSHHOME to the path
export PATH=$PATH:$SSHHOME/.sshrc.d
# To use simply create a $HOME/.sshrc.d folder with any configurations you want to use
# and a $HOME/.sshrc file with generic shell configurations, then simply use like ssh
sshrc [user@]<hostname>
#!/usr/bin/env bash
function sshrc() {
local SSHHOME=${SSHHOME:=~}
if [ -f $SSHHOME/.sshrc ]; then
local files=.sshrc
if [ -d $SSHHOME/.sshrc.d ]; then
files="$files .sshrc.d"
fi
SIZE=$(tar cfz - -h -C $SSHHOME $files | wc -c)
if [ $SIZE -gt 65536000 ]; then
echo >&2 $'.sshrc.d and .sshrc files must be less than 64000kb\ncurrent size: '$SIZE' bytes'
exit 1
fi
if [ -z "$CMDARG" -a ! -e ~/.sshrc.d/.hushlogin ]; then
WELCOME_MSG="
if [ ! -e ~/.hushlogin ]; then
if [ -e /etc/motd ]; then cat /etc/motd; fi
if [ -e /etc/update-motd.d ]; then run-parts /etc/update-motd.d/ 2>/dev/null; fi
last -F \$USER 2>/dev/null | grep -v 'still logged in' | head -n1 | awk '{print \"Last login:\",\$4,\$5,\$6,\$7,\$8,\"from\",\$3;}'
fi
"
else
WELCOME_MSG=""
fi
ssh -t "$DOMAIN" $SSHARGS "
command -v openssl >/dev/null 2>&1 || { echo >&2 \"sshrc requires openssl to be installed on the server, but it's not. Aborting.\"; exit 1; }
$WELCOME_MSG
export SSHHOME=\$(mktemp -d -t .$(whoami).sshrc.XXXX)
export SSHRCCLEANUP=\$SSHHOME
trap \"rm -rf \$SSHRCCLEANUP; exit\" 0
echo $'"$(cat "$0" | openssl enc -base64)"' | tr -s ' ' $'\n' | openssl enc -base64 -d > \$SSHHOME/sshrc
chmod +x \$SSHHOME/sshrc
echo $'"$( cat << 'EOF' | openssl enc -base64
if [ -r /etc/profile ]; then source /etc/profile; fi
if [ -r ~/.bash_profile ]; then source ~/.bash_profile
elif [ -r ~/.bash_login ]; then source ~/.bash_login
elif [ -r ~/.profile ]; then source ~/.profile
fi
export PATH=$PATH:$SSHHOME
source $SSHHOME/.sshrc;
EOF
)"' | tr -s ' ' $'\n' | openssl enc -base64 -d > \$SSHHOME/sshrc.bashrc
echo $'"$( cat << 'EOF' | openssl enc -base64
#!/usr/bin/env bash
exec bash --rcfile <(echo '
[ -r /etc/profile ] && source /etc/profile
if [ -r ~/.bash_profile ]; then source ~/.bash_profile
elif [ -r ~/.bash_login ]; then source ~/.bash_login
elif [ -r ~/.profile ]; then source ~/.profile
fi
source '$SSHHOME'/.sshrc;
export PATH=$PATH:'$SSHHOME'
') "$@"
EOF
)"' | tr -s ' ' $'\n' | openssl enc -base64 -d > \$SSHHOME/bashsshrc
chmod +x \$SSHHOME/bashsshrc
echo $'"$(tar czf - -h -C $SSHHOME $files | openssl enc -base64)"' | tr -s ' ' $'\n' | openssl enc -base64 -d | tar mxzf - -C \$SSHHOME
export SSHHOME=\$SSHHOME
echo \"$CMDARG\" >> \$SSHHOME/sshrc.bashrc
bash --rcfile \$SSHHOME/sshrc.bashrc
"
else
echo "No such file: $SSHHOME/.sshrc" >&2
exit 1
fi
}
function sshrc_parse() {
while [[ -n $1 ]]; do
case $1 in
-b | -c | -D | -E | -e | -F | -I | -i | -L | -l | -m | -O | -o | -p | -Q | -R | -S | -W | -w )
SSHARGS="$SSHARGS $1 $2"; shift ;;
-* )
SSHARGS="$SSHARGS $1" ;;
*)
if [ -z "$DOMAIN" ]; then
DOMAIN="$1"
else
local SEMICOLON=$([[ "$@" = *[![:space:]]* ]] && echo '; ')
CMDARG="$@$SEMICOLON exit"
return;
fi
;;
esac
shift
done
if [ -z $DOMAIN ]; then
ssh $SSHARGS; exit 1;
fi
}
command -v openssl >/dev/null 2>&1 || { echo >&2 "sshrc requires openssl to be installed locally, but it's not. Aborting."; exit 1; }
sshrc_parse "$@"
sshrc
@jordangarrison
Copy link
Author

jordangarrison commented May 28, 2020

Please note that I did not write sshrc.sh, I just can't find it anymore and didn't want it to be lost to time and the internet.

@ypid-work
Copy link

It is not lost (https://github.com/buehmann/sshrc). I also found https://github.com/fsquillace/kyrat but currently also use sshrc. Copyright/authors of code can be expressed with https://reuse.software/.

@jordangarrison
Copy link
Author

jordangarrison commented Mar 17, 2022

Nice @ypid-work! Never seen the kyrat tool before, might have to make the switch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment