ssht - exécution commande ssh

ssht - exécution commande ssh

Notes › _DIFFUSION

Voici une solution simple avec une fonction Bash ssht. Elle lit ~/.ssh_servers_private, cherche l’alias dans la première colonne, puis lance SSH avec l’utilisateur, l’hôte, le port et — si renseignée — la clé privée correspondante dans ~/.ssh/.

Fichier CSV

Liste des clients SSH

1
~/.ssh_servers_private

Puis limitez ses permissions, car il contient des informations de connexion privées :

1
chmod 600 ~/.ssh_servers_private

Le fichier doit conserver le séparateur ; et l’en-tête :

Alias;User;IPouDomain;Port_SSH;SSH_Key;Ping;IP4_6
e6230l;yano;192.168.0.21;56230;e6230;N;4
cwwk;yick;192.168.0.205;55205;yick-ed25519;Y;4
proxy;yick;rnmkcy.eu;55205;yick-ed25519;Y;4
tinyleno;tiny;192.168.0.45;55045;tiny700;;4

Script indépendant

version complète de ~/.local/bin/ssht qui gère les deux nouveaux champs :

  • Ping :
    • Y → teste la joignabilité ICMP.
    • N ou vide → affiche ---, sans lancer de ping.
  • IP4_6 :
    • 4 → teste avec ping -4.
    • 6 → teste avec ping -6.
  • Sans argument, ssht affiche le tableau des serveurs et leur état.
  • Avec un alias, ssht cwwk, la commande lance SSH comme précédemment.
  • Les statuts IP4 et IP6 sont colorés en vert ; Non est rouge ; --- reste neutre.

Le test utilise une seule requête ICMP (-c 1) et un délai court (-W 1). Sous Linux, ping retourne un code de sortie nul si une réponse est reçue ; ping -6 force le test IPv6

Créer dossier

1
mkdir -p $HOME/.local/bin

Vérifiez que ~/.local/bin fait bien partie du PATH :

1
echo "$PATH"

Si nécessaire, ajoutez ceci dans ~/.bashrc ou ~/.zshrc :

1
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

Puis rechargez votre shell :

1
source ~/.bashrc

Fichier ~/.local/bin/ssht

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash

set -u

CSV_FILE="$HOME/.ssh_servers_private"
SSH_DIR="$HOME/.ssh"

# Couleurs : désactivées automatiquement lorsque la sortie n'est pas un terminal.
if [[ -t 1 ]]; then
    COLOR_GREEN=$'\033[1;32m'
    COLOR_RED=$'\033[1;31m'
    COLOR_RESET=$'\033[0m'
else
    COLOR_GREEN=''
    COLOR_RED=''
    COLOR_RESET=''
fi

usage() {
    cat <<'EOF'
Usage :
  ssht                  Affiche les serveurs et leur état Ping
  ssht <alias>          Ouvre une connexion SSH
  ssht -h | --help      Affiche cette aide
EOF
}

check_csv() {
    if [[ ! -r "$CSV_FILE" ]]; then
        echo "Erreur : fichier introuvable ou illisible : $CSV_FILE" >&2
        exit 1
    fi
}

ping_status() {
    local host="$1"
    local ping_enabled="$2"
    local ip_version="$3"

    # Ping=N, vide, ou valeur différente de Y : aucun test.
    if [[ "${ping_enabled^^}" != "Y" ]]; then
        printf '%s---%s' "$COLOR_RESET" "$COLOR_RESET"
        return 0
    fi

    # ping -4 pour IPv4, ping -6 pour IPv6.
    # -c 1 : une seule sonde ; -W 1 : attente max de 1 seconde.
    if [[ "$ip_version" == "6" ]]; then
        if ping -6 -c 1 -W 1 "$host" >/dev/null 2>&1; then
            printf '%sIP6%s' "$COLOR_GREEN" "$COLOR_RESET"
        else
            printf '%sNon%s' "$COLOR_RED" "$COLOR_RESET"
        fi
    else
        if ping -4 -c 1 -W 1 "$host" >/dev/null 2>&1; then
            printf '%sIP4%s' "$COLOR_GREEN" "$COLOR_RESET"
        else
            printf '%sNon%s' "$COLOR_RED" "$COLOR_RESET"
        fi
    fi
}

list_servers() {
    local alias user host port key ping_enabled ip_version status

    printf '%s\n' '================================================================================'
    printf '|%-6s|%-10s|%-10s|%-16s|%-6s|%-20s|\n' \
        'Ping' 'Alias' 'User' 'IPv4v6' 'Port' 'Clé SSH'
    printf '%s\n' '--------------------------------------------------------------------------------'

    while IFS=';' read -r alias user host port key ping_enabled ip_version; do
        # Ignore l'en-tête, les lignes vides et les lignes de commentaire.
        [[ "$alias" == "Alias" ]] && continue
        [[ -z "$alias" ]] && continue
        [[ "$alias" == \#* ]] && continue

        # Valeurs par défaut si Port ou IP4_6 sont vides.
        port="${port:-22}"
        ip_version="${ip_version:-4}"

        status="$(ping_status "$host" "$ping_enabled" "$ip_version")"

        # Les séquences ANSI de couleur faussent printf si elles sont incluses
        # dans une largeur fixe. On affiche donc le statut séparément.
        printf '|'
        printf '%-6s' "$status"
        printf '|%-10s|%-10s|%-16s|%-6s|%-20s|\n' \
            "$alias" "$user" "$host" "$port" "$key"
    done < "$CSV_FILE"

    printf '%s\n' '================================================================================'
}

connect_ssh() {
    local wanted_alias="$1"
    local alias user host port key ping_enabled ip_version
    local found=0
    local ssh_args=()

    while IFS=';' read -r alias user host port key ping_enabled ip_version; do
        [[ "$alias" == "Alias" ]] && continue
        [[ -z "$alias" ]] && continue
        [[ "$alias" == \#* ]] && continue

        if [[ "$alias" == "$wanted_alias" ]]; then
            found=1
            break
        fi
    done < "$CSV_FILE"

    if [[ "$found" -ne 1 ]]; then
        echo "Erreur : alias inconnu : $wanted_alias" >&2
        echo >&2
        list_servers
        exit 1
    fi

    if [[ -z "$user" || -z "$host" ]]; then
        echo "Erreur : entrée CSV invalide pour l'alias '$wanted_alias'." >&2
        exit 1
    fi

    port="${port:-22}"

    ssh_args+=(-p "$port")

    # Pour une adresse IPv6 littérale, SSH accepte user@adresse.
    # La forme entre crochets est utilisée par SSH pour certains contextes,
    # mais ne doit pas être imposée ici.
    if [[ -n "$key" ]]; then
        local key_path="$SSH_DIR/$key"

        if [[ ! -f "$key_path" ]]; then
            echo "Erreur : clé SSH introuvable : $key_path" >&2
            exit 1
        fi

        ssh_args+=(-i "$key_path")
    fi

    echo "Connexion : $user@$host:$port"
    exec ssh "${ssh_args[@]}" "$user@$host"
}

check_csv

case "${1:-}" in
    "")
        list_servers
        ;;
    -h|--help)
        usage
        ;;
    *)
        connect_ssh "$1"
        ;;
esac

Puis rendez-le exécutable :

1
chmod 700 ~/.local/bin/ssht

Utilisation

Afficher la liste avec le test de disponibilité :

1
ssht

Connexion SSH par alias :

1
ssht cwwk

Ce dernier construira bien :

1
ssh -p 55205 -i /home/yann/.ssh/yick-ed25519 yick@192.168.0.205

Pour votre ligne IPv6 :

1
skrime;skim;2a14:7c0:1002:19a8::;51002;skrime-ed25519;Y;6

la liste lancera :

1
ping -6 -c 1 -W 1 2a14:7c0:1002:19a8::

et affichera soit IP6 en vert, soit Non en rouge.

Exemple d’affichage

Avec les couleurs activées dans un terminal, l’apparence sera du type :

1
2
3
4
5
6
7
8
9
================================================================================
|Ping  |Alias     |User      |IPv4v6          |Port  |Clé SSH             |
--------------------------------------------------------------------------------
|IP4   |cwwk      |yick      |192.168.0.205   |55205 |yick-ed25519        |
|IP4   |proxy     |yick      |rnmkcy.eu       |55205 |yick-ed25519        |
|---    |tinyleno |tiny      |192.168.0.45    |55045 |tiny700             |
|IP4   |proxmox  |leno      |192.168.0.215   |55215 |m93p-ed25519        |
|IP6   |skrime   |skim      |2a14:7c0:1002:19a8::|51002 |skrime-ed25519 |
================================================================================

Point important sur les couleurs

Dans votre premier exemple, l’alignement peut être cassé si les codes ANSI de couleur sont placés directement dans une colonne calculée avec printf '%-6s'. La version ci-dessus sépare donc l’écriture du statut de celle des autres colonnes : le tableau reste aligné tout en laissant IP4 ou IP6 vert et Non rouge.

Option utile : test plus rapide

Votre CSV contient actuellement 13 hôtes avec Ping=Y. Avec un délai d’une seconde pour chaque machine hors ligne, la liste peut prendre environ 13 secondes dans le pire cas, car les pings sont effectués séquentiellement.

Pour accélérer, réduisez le délai :

1
ping -4 -c 1 -W 1 "$host"

en :

1
ping -4 -c 1 -W 0.5 "$host"

Cependant, selon la version Linux de ping, -W peut n’accepter que des secondes entières. La valeur -W 1 est donc le choix le plus portable et fiable.