#!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 function display_help() { uecho "$scriptname: se connecter par ssh à un ou plusieurs hôtes USAGE $scriptname host [options] $scriptname @hostsfile [options] $scriptname -R hosts... OPTIONS host @hostsfile Spécifier un hôte distant sur lequel faire la connexion. Plusieurs hôtes peuvent être spécifiées, en les séparant par ':', e.g. host1:host2 La forme @hostsfile permet de lire la liste des hôtes depuis le fichier hostsfile, à raison d'un hôte par ligne. [options] Les arguments et options de ssh doivent se trouver *APRES* host, pour simplifier leur analyse. Les options suivantes doivent se trouver *AVANT* le premier argument: -S SSH Spécifier l'exécutable à utiliser pour lancer ssh. -R Lancer 'ssh-keygen -R' pour chacun des hôtes spécifiés. Par exemple: $scriptname -R host.tld est équivalent à: ssh-keygen -R host.tld ssh-keygen -R host ssh-keygen -R 10.10.1.5 si l'adresse ip de host.tld est 10.10.1.5" } source "$(dirname "$0")/ulib/ulib" && urequire DEFAULTS || exit 1 __PARSED_HOSTS=() __PARSED_FILES=() function parse_hostsfile() { # Lire chacun des fichiers $* et initialiser __PARSED_HOSTS avec la liste # des hôtes mentionnés dans les fichiers. local inputfile basedir inputs input for inputfile in "$@"; do inputfile="$(abspath "$inputfile")" array_contains __PARSED_FILES "$inputfile" && { ewarn "$(ppath "$inputfile"): inclusion récursive" continue } array_add __PARSED_FILES "$inputfile" basedir="$(dirname "$inputfile")" array_from_lines inputs "$(<"$inputfile" filter_conf)" || { ewarn "$inputfile: fichier ingnoré" continue } for input in "${inputs[@]}"; do if [ "${input#@}" != "$input" ]; then # fichier inclus parse_hostsfile "$(abspath "${input#@}" "$basedir")" else array_addu __PARSED_HOSTS "$input" fi done done } function __dot_is_localhost() { [ "$1" == "." ] && echo "localhost" || echo "$1"; } function fix_hosts() { # Si hosts contient des éléments multiple, comme a:b, séparer ces # éléments. i.e (a b:c) --> (a b c) # Supporter la syntaxe @hostsfile qui permet de charger la liste des hôtes # depuis un fichier. # Remplacer aussi les '.' par 'localhost' array_fix_paths hosts local -a _hosts _tmphosts host for host in "${hosts[@]}"; do host="${host%/}" if [ "${host#@}" != "$host" ]; then __PARSED_HOSTS=() parse_hostsfile "${host#@}" array_fix_paths __PARSED_HOSTS array_extendu _hosts __PARSED_HOSTS else array_addu _hosts "$host" fi done array_copy hosts _hosts array_map hosts __dot_is_localhost } action=ssh quiet= tty= options=() ssh= parse_opts + "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -q quiet=1 \ -t tty=1 \ -o options \ -S:,--ssh ssh= \ -R,--remove action=remove \ @ args -- "$@" && set -- "${args[@]}" || die "$args" if [ "$action" == "ssh" ]; then [ -n "$1" ] || die "Vous devez spécifier l'hôte sur lequel faire la connexion" hosts=("$1"); shift fix_hosts args=(${quiet:+-q} ${tty:+-t}) for option in "${options[@]}"; do args=("${args[@]}" -o "$option") done args=("${args[@]}" "$@") [ -n "$ssh" ] || ssh=ssh [ "${#hosts[*]}" -gt 1 ] && showtitle=1 || showtitle= for host in "${hosts[@]}"; do [ -n "$showtitle" ] && etitle "$host" splituserhost "$host" user host "$ssh" "${user:+$user@}$host" "${args[@]}" [ -n "$showtitle" ] && eend done elif [ "$action" == "remove" ]; then urequire ipcalc function remove() { estep "$1" ssh-keygen -R "$1" >&/dev/null } [ -n "$1" ] || die "Vous devez spécifier les hôtes à supprimer de ~/.ssh/known_hosts" hosts=("$@") fix_hosts etitle "Suppression des entrées dans ~/.ssh/known_hosts" allhosts=("${hosts[@]}") for host in "${allhosts[@]}"; do if ipcalc_checkip "$host" >/dev/null; then ip="$host" remove "$ip" resolv_hosts hosts "$ip" for host in "${hosts[@]}"; do remove "$host" hostname="${host%%.*}" [ "$hostname" != "$host" ] && remove "$hostname" done else remove "$host" hostname="${host%%.*}" [ "$hostname" != "$host" ] && remove "$hostname" resolv_ips ips "$host" for ip in "${ips[@]}"; do remove "$ip" done fi done eend fi