Mastodon
Writings / Have an SSH user config? Fuzzy find your hosts.

Mon, 8 Jan 2024

Have an SSH user config? Fuzzy find your hosts.

Updated on Wed, 20 Mar 2024

Assuming you are familiar with both the SSH (user) config file ~/.ssh/config and the fuzzy finder fzf (if not, see man fzf and man ssh_config) you can create two scripts: ssh-hosts and fzf-ssh. The former to list the hosts in your ~/.ssh/config file, the latter to SSH into one of these hosts.

  1. The ssh-hosts script:
#!/usr/bin/env bash

ssh_hosts="$(grep -E 'Host [a-z0-9-]*$' ~/.ssh/config | awk '{print $2}')"

echo "$ssh_hosts"

It uses a regular expression (-E flag) to find the Host <hostname> lines in the config. Using awk we can print this second column <hostname> for each of these lines, i.e. the name of of the host.

  1. Having created the ssh-hosts script, you can use it in other scripts. E.g. the fzf-ssh script will pipe ssh-hosts into the fuzzy finder so you can find and select the host you want to SSH into:
#!/usr/bin/env bash

ssh "$(ssh-hosts | fzf)"

Two minimal scripts, but possibly useful if you have configured many SSH hosts and don’t neccessarily like typing / tabbing to find one of them. ssh-hosts can also be reused in other scripts, e.g. if you would like a basic way to execute a command on each of your hosts:

ssh-hosts | xargs -I {} ssh {} <command>
(Edit 2024-03-20)
For example, I like to use the following script to quickly back up from the home level directories on some server.
#!/usr/bin/env bash

selected_hosts="$(ssh-hosts | fzf -m)"

for host in $selected_hosts; do
    echo "Saving $host"
    directories="$(ssh "$host" ls | fzf -m)"
    for directory in $directories; do
        echo "Saving $host:$directory"
        ssh "$host" "(tar cvzf - ~/$directory)" > "${host}_${directory}.tar.gz"
    done
done

For example, this is what the $HOME of my server looks like, the directories contain docker configurations.

~/
β”œβ”€β”€ directus
β”œβ”€β”€ gitea
β”œβ”€β”€ navidrome
β”œβ”€β”€ nginx-reverse-proxy-manager
β”œβ”€β”€ remark42
β”œβ”€β”€ signal-cli-rest-api
└── webhook

Now I can simply run save-ssh-host, select the hosts I want to back up, and then select the directories I want to back up.

$> save-ssh-host

  server2
  server1
  pi-2
  pi-1
❭ desk
  6/6 (0) ────────────────────────────────────────────────────────────
>
$> save-ssh-host

Saving server2
  webhook
  taskrc
  signal-cli-rest-api
  remark42
  nginx-reverse-proxy-manager
  navidrome
  gitea
❭ directus
  8/8 (0) ────────────────────────────────────────────────────────────
>

The directories are archived and saved in the current directory.

Comments