Some Tips To Make SSH/SCP Usage More Convenient
I guess many of us rely heavily on ssh/scp to access/maintain remote hosts. In this short article I would like to share some experiences I find useful for ssh/scp usage.
First let's have a look how things started:
- In the beginning: ssh 192.168.0.1
- Then we get another host, this time with a different user id: ssh root@192.168.0.2
- Since we use those commands quite often and it's not fun to type the ip address over and over, let's simplify this a bit by putting those IP's to /etc/hosts and using hostnames instead of IP's: ssh host1, resp. ssh root@host2
- Then we got another host to maintain, this time with a non-standard port for ssh: ssh -p 222 admin@host3
- Hm it's getting a bit messy, let's simplify this: for each host let's have a simple script so we don't need to remember the user id and port to connect. Let's put the above commands to ssh-host1, ssh-host2 and ssh-host3. Great, now we can enjoy the auto-completion feature of shells to access those hosts, and forget all those parameters...
- Then we need to scp something to these hosts: hm it's getting messy again, let's create another set of scripts for scp...
- Then we get another host...
- It's not hard to imagine how this would continue.
I use a simple trick to get out of this mess: I have a simple script named ssh-generic that looks as follows:
#!/bin/bash port="22" case "$0" in *-host1) account="myid@192.168.0.1" ;; *-host2) account="root@192.168.0.2" ;; *-host3) account="admin@192.168.0.3" port="222" ;; *) echo "unsupported name: $0" exit 1 ;; esac case "$0" in */ssh-*) echo running ssh -p $port $account "$@" ssh -p $port $account "$@" ;; */scp-to-*) echo running scp -P $port "$@" $account: scp -P $port "$@" $account:$scpdir ;; */scp-from-*) echo scp -P $port $account:$1 . scp -P $port $account:$1 . ;;
*) echo "unsupported name: $0" exit 1 ;; esac
Then I make ssh-host1, scp-to-host1 and scp-from-host1 as symlink to the above script (ie ssh-generic). Usage is trivial:
- To ssh to host1: ssh-host1
- To copy a file to host1: scp-to-host1 <filename>
- To copy a file from host1: scp-from-host1 <filename>
Similar for host2 and host3. When we get another host, it's easy to edit ssh-generic, add the relevant entry and make needed symlinks. For example, let's add another host with ip 192.168.0.4, port for ssh 2222 and user id admin2. We want to access this host by simply saying ssh-host4. This turns out to be easy:
- Edit ssh-generic and add the follwing lines to the right place (left as exercise for readers):
*-host4) account="admin2@192.168.0.4" port="2222" ;;
- Make ssh-host4, scp-to-host4 and scp-from-host4 as symlink to ssh-generic
A bonus is that we can say in the command line eg ssh-host<Tab> to free ourselves from remembering the hostnames, connection details and hence from making mistakes. There are some cosmetic details that I left out from the script for clarity, like automatically setting the title of current xshell before running ssh/scp, or a dryrun option for the script.
I also have a companion script that can be used to ease uploading ssh keys. I named it "enable-ssh" (a bit poor chosen name, should be renamed to something better) and it looks as follows:
if test -z "$1"; then echo Usage: $0 '[-p <port>] <host>' exit 1 fi if ! test -s $HOME/.ssh/id_rsa.pub; then ssh-keygen -t rsa fi cd cat $HOME/.ssh/id_rsa.pub | \ ssh "$@" "mkdir -p .ssh; touch .ssh/authorized_keys; cat >> .ssh/authorized_keys"
Usage:
- To upload ssh key to a host with the standard port and the same user id: enable-ssh host1
- To upload ssh key to a host with non-standard port and different user id:
- First try to ssh to that host to find out the needed parameters (we don't want to remember anything that we have written down, don't we?): ssh-host4
- The above comment will write the command used to connect to host4: running ssh -p 2222 admin2@192.168.0.4
- Run in another terminal: enable-ssh -p 2222 admin2@192.168.0.4
That's it. I hope you find this useful.