投稿日:

CLIでSSH接続先管理・スクリプト化

はじめに

複数の仮想マシンのSSH接続先を簡易的に管理する方法がないかChatGPTに相談したときのメモ.
SSH接続先を管理するCLIツール自体はいくらでもありそうだったが,そんなに大した機能もいらなかったので自作のスクリプトに落ち着いた.

管理方法

~/.ssh/config にホスト情報をまとめる

最も基本的な方法

# ~/.ssh/config

Host dev-server
  HostName 192.168.1.100
  User ubuntu
  Port 22
  IdentityFile ~/.ssh/id_rsa

Host nas
  HostName 192.168.1.101
  User admin
  Port 2222

接続時はHostを指定

ssh dev-server
ssh nas

接続先の一覧表示

ホスト名を一覧化

grep '^Host ' ~/.ssh/config | awk '{print $2}'

接続先IPアドレスも表示

awk '/^Host / {host=$2} /^  HostName/ {print host " -> " $2}' ~/.ssh/config

fzf(対話型検索ツール)と組み合わせるとメニューっぽくなる

ssh $(grep '^Host ' ~/.ssh/config | awk '{print $2}' | fzf)

スクリプト化

ベース

#!/bin/bash
# sshmenu.sh

host=$(grep '^Host ' ~/.ssh/config | awk '{print $2}' | fzf)
if [ -n "$host" ]; then
  ssh "$host"
fi

IPアドレスも表示

#!/bin/bash

# ~/.ssh/config をパースして Host と HostName を抽出
entries=$(awk '
  $1 == "Host"     { host=$2; next }
  $1 == "HostName" { print host "\t" $2 }
' ~/.ssh/config)

# fzf で選択(表示:ホスト名+ホスト名/IP、選択:ホスト名)
host=$(echo "$entries" | fzf --with-nth=1,2 | awk '{print $1}')

# 選択されたら接続
if [ -n "$host" ]; then
  ssh "$host"
fi

~/.ssh/configの例:

Host dev-server
  HostName 192.168.1.10

Host nas
  HostName 192.168.1.20

Host my-vps
  HostName vps.example.com

出力:

dev-server     192.168.1.10
nas            192.168.1.20
my-vps         vps.example.com

Port や IdentityFile の有無でアイコンをつける

Port や IdentityFile の有無を調べて,表示にアイコンや記号を付ける.

🔑 → IdentityFile が設定されている
🔌 → Port が設定されている

#!/bin/bash

selected_host=$(
awk -v iconKey="🔑" -v iconPort="🔌" '
  BEGIN { host = ""; hostName = ""; port = ""; identity = "" }

  $1 == "Host" {
    if (host != "") {
      print formatLine(host, hostName, port, identity)
    }
    host = $2
    hostName = ""; port = ""; identity = ""
    next
  }

  $1 == "HostName"     { hostName = $2 }
  $1 == "Port"         { port = $2 }
  $1 == "IdentityFile" { identity = $2 }

  END {
    if (host != "") {
      print formatLine(host, hostName, port, identity)
    }
  }

  function formatLine(h, hn, p, i,   symbols) {
    symbols = ""
    if (i != "") { symbols = symbols iconKey " " }
    if (p != "") { symbols = symbols iconPort }
    return sprintf("%-20s %-25s %s", h, hn, symbols)
  }
' ~/.ssh/config | fzf --ansi | awk '{print $1}'
)

# 実行
[ -n "$selected_host" ] && exec ssh "$selected_host"

出力:

dev-server     192.168.1.10     🔑 🔌
 nas           192.168.1.20     🔌
 my-vps        vps.example.com 🔑

備忘

実行方法

  1. ファイルに保存(例:~/sshmenu.sh)

  2. 実行権限を付ける

chmod +x ~/sshmenu.sh
  1. 実行
~/sshmenu.sh

環境変数(PATH)の設定

bashの場合は~/.bashrcの末尾に以下のように追記

export PATH="$PATH:$HOME/bin"