Предлагаю вашему вниманию скрипт, удобную менюшку, для удаленных сессий по SSH и Telnet

Возможности:
 - Автологин SSH и Telnet сессий
 - Весьма не сложный в настройке конфиг
 - Многоуровневое меню (поддерживаются суб-меню любой глубины)
- К любому суб-меню можно "приклеить ярлык" и обращаться на прямую к этому меню из командной строки
 - Одна железяка может иметь несколько ip адресов.
 - Описания или заметки к каждой железке отображаются в меню
 - Open Source

Зависимости:
libjson-xs-perl, libexpect-perl

Установка:
sudo apt-get install libjson-xs-perl libexpect-perl
копируем cm к примеру в /usr/local/bin
и даём бит исполняемый:
chmod +x /usr/local/bin/cm
создаем свой конфиг в /home/username/.cm

Использование:
cm [arg]

Немного предыстории:
Мне по долгу службы, приходиться часто лазить на удалённые железяки и серверы по ssh. Так как их приличное количество и запомнить все IP и хостнеймы просто не возможно, было решено написать простейшую менюшку на shell (скрипт авторизации написал ещё давно). Но копаться каждый раз в теле скрипта, для того чтобы добавить новую железяку надоело. Начали появляться железяки с уникальным логином/паролем (которые тоже надо помнить). В общем было решено написать нормальную менюшку на Perl. Где можно указать логин/пароль на конкретную железяку, делать суб-меню любой сложности. В общем чтобы было удобно.
Под винду полно подобного софта - под линукс ничего подобного не видел.

Вопросы, комментарии приветствуются. Если окажется, что это нужно кому-то кроме меня, будем развиваться ;)


Конфиг:
Конфиг в формате JSON. С первого взгляда может не понятен, но на самом деле довольно прост.
Подробности можно узнать тут: http://ru.wikipedia.org/wiki/JSON

name - имя пункта меню
menu - при наличии этой опции означает, что это суб-меню
arg - передавая аргумент указанный здесь из командной строки, можно сразу перейти на это суб-меню ip - ip-адрес. Если этот пункт отсутствует, то пытается подключиться по name. При наличии нескольких ip адресов, появляется меню с выбором
login - логин от железяки. Может использоваться без password для SSH сессий
password - пароль от железяки. Полезно для коммутаторов, маршрутизаторов
description - описание, заметка или что-то вроде того
type - если указан telnet, то подключаться будет по телнету

конфиг должен лежать в домашней директории:
~/.cm

Структура конфига очень напоминает хэши и массивы perl.


Примеры конфига:

1)--------------------------------------------------
[{
        "name": "server1",
        "ip": "192.168.11.9"
},
{
        "name": "svn.corp",
        "description": "SVN-Server"
},
{
        "name": "Активное оборудование"
        "arg": "a",
        "menu": [{
                            "name": "Коммутаторы",
                            "menu": [{
                                                "name": "192.168.11.2",
                                                "login": "admin",
                                                "password": "123456",
                                                "type": "telnet"
                                            },
                                            {
                                                "name": "192.168.11.3,
                                                "login": "admin",
                                                "password": "123456",
                                                "type": "telnet"
                                            }]
                        },
                        {
                            "name": "Маршрутизаторы",
                            "menu": [{
                                                "name": "main",
                                                "ip": "192.168.11.1"
                                            }]
                        }]
}]


2)------------------------------------------------------------------------------------------
[{
        "name": "Servers on VM",
        "arg": "vm",
        "menu": [{
                        "name": "SVN",
                        "ip": [
                                "192.168.4.9",
                                "98.33.74.2"
                            ],
                        "login": "user44"
                },
                {
                        "name": "kvm.pika.corp",
                        "login": "root",
                        "description": "Hypervisor"
                },
                {
                        "name": "ngenix.r55.ru"
                }]
},
{
        "name": "Commutators & Routers",
        "arg": "c",
        "menu": [{
                        "name": "192.168.4.1",
                        "description": "Users GW",
                        "login": "admin",
                        "password": "1234secret"
                },
                {
                        "name": "192.168.1.10",
                        "login": "admin",
                        "password": "1234secret",
                        "type": "telnet"
                },
                {
                        "name": "E650-M9-AGG-10",
                        "ip": "10.10.3.9",
                        "description": [
                            "MSK-IX (4)",
                            "DATA-IX (2)"
                            ],
                        "login": "support",
                        "password": "342r32r2ddd"
                }]
}]






--
С уважением,
Alex Emergy

[{
        "name": "Servers on VM",
        "arg": "vm",
        "menu": [{
                        "name": "SVN",
                        "ip": [
                                "192.168.4.9",
                                "98.33.74.2"
                            ],
                        "login": "user44"
                },
                {
                        "name": "kvm.pika.corp",
                        "login": "root",
                        "description": "Hypervisor"
                },
                {
                        "name": "ngenix.r55.ru"
                }]
},
{
        "name": "Commutators & Routers",
        "arg": "c",
        "menu": [{
                        "name": "192.168.4.1",
                        "description": "Users GW",
                        "login": "admin",
                        "password": "1234secret"
                },
                {
                        "name": "192.168.1.10",
                        "login": "admin",
                        "password": "1234secret",
                        "type": "telnet"
                },
                {
                        "name": "E650-M9-AGG-10",
                        "ip": "10.10.3.9",
                        "description": [
                            "MSK-IX (4)",
                            "DATA-IX (2)"
                            ],
                        "login": "support",
                        "password": "342r32r2ddd"
                }]
}]
#!/usr/bin/perl 

my $version = '1.0';

#===============================================================================
#
#         FILE:  connection-manager.pl
#
#        USAGE:  ./connection-manager.pl [-s] [arg]
#
#  DESCRIPTION:  Connection Manager
#
#       AUTHOR:  Alex Emergy
#      CREATED:  21.04.2011 18:28:14
#      DEPENDS:  libjson-xs-perl, libexpect-perl
#
#===============================================================================

use strict;
use warnings;
use Data::Dumper;
use Expect;
use JSON::XS;
use Getopt::Std;

$Getopt::Std::STANDARD_HELP_VERSION = 1;

our ($opt_s);
getopts('s');

my $menu_file = $ENV{HOME} . "/.cm";
die "Файла конфигурации $menu_file не 
существует!\n" unless (-e $menu_file);
    

# read menu file to $source_json
my $source_json;
open SRC, '<', $menu_file or die "Cannot open menu file: $!";
while (my $line = <SRC>) {
    $source_json .= $line;
}
close(SRC);

# ARRAY from JSON
my $json_xs = JSON::XS->new();
my $config = $json_xs->decode($source_json);
die "Error in config" if ((!$config) or (ref($config) ne 'ARRAY'));

my $arg = shift(@ARGV);
$config = ck_arg($config, $config, $arg) if ($arg);

show_menu($config);

sub ck_arg {
    my $json_obj = $_[0];
    my $back = $_[1];
    my $ARG = $_[2];
    my $r;
    foreach my $hash (@$json_obj) {
        return $hash->{menu} if ($ARG eq $hash->{arg});
        if ($hash->{menu}) {
            $r = ck_arg($hash->{menu}, $back, $ARG);
            return $r if ($r);
        }
    }
    return $json_obj if ($back eq $json_obj);
}

sub show_menu {
    my $change;
    my $json_obj = $_[0];

LABEL:
    my $count = 1;

    system("clear");

    foreach my $item (@$json_obj) {
        my $estring = '';
        $estring = "=>" if ($item->{menu});
        $estring .= ArrayToString($item->{description}) if $item->{description};
        $estring .= ArrayToString($item->{ip}) . "\n" if (($item->{ip}) and 
($item->{ip} ne $item->{name}));
        print "\033[1m" . $count . ") " . $item->{name} . "\033[0m " . $estring 
. "\n";
        $change->{$count} = $item->{name};
        $count++;
    }
    $count--;
    print "\n[1-$count] - Выбор, Enter - Назад/Выход\n";
    my $pick;
    chomp($pick = <STDIN>);
    return 0 if ($pick eq '');
    goto LABEL unless (ck_valid_change($pick, $count));
    ck_sub_menu($change->{$pick}, $json_obj);
    goto LABEL;
}

sub ck_sub_menu {
    my $change = $_[0];
    my $json_obj = $_[1];
    my $res;

    system("clear");

    foreach my $item (@$json_obj) {
        if ($item->{name} eq $change) {
            if ($item->{menu}) {
                show_menu($item->{menu});
            } else {
                my $host;
                unless ($item->{ip}) {
                    $host = $item->{name};
                } else {
                    $host = $item->{ip};
                }
                connect_to($host, $item->{login}, $item->{password}, 
$item->{type});
            }
        }
    }
    return $res;
}

sub ip_sub_menu {
    my $ips = $_[0];
    my $menu;
    foreach my $ip (@$ips) {
        my $hash;
        $hash->{'name'} = $ip;
        $hash->{'ip'} = $ip;
        $hash->{'ipmenu'} = "menu";
        push(@$menu, $hash);
    }
    show_menu($menu);
}

sub connect_to {
    my $ip = $_[0];
    my $login = $_[1];
    my $password = $_[2];
    my $type = $_[3];

    $type = 'ssh' unless($type);

    if (ref($ip) eq 'ARRAY') {
        ip_sub_menu($ip);
        return 0;
    }

    unless($password) {
        if ($type eq 'telnet') {
            system("telnet $ip");
        } else {
            unless($login) {
                system("ssh $ip");
            } else {
                system("ssh $login\@$ip");
            }
        }
    } else {
        my $timeout = 6;
        my $exp = new Expect;

        if ($type eq 'telnet') {
            $exp->spawn("telnet $ip") or die "Cannot connect to address: $!\n";
        } else {
            $exp->spawn("ssh $login\@$ip") or die "Cannot connect to address: 
$!\n";
        }

        $exp->expect($timeout,
                [ "assword" => sub {
                        $exp->send("$password\n");
                }],
                [ "Are you sure you want to continue connecting" => sub {
                        $exp->send("yes\n");
                        exp_continue;
                }],
                [ "sername" => sub {
                        $exp->send("$login\n");
                        exp_continue;
                }],
                [ "ogin" => sub {
                        $exp->send("$login\n");
                        exp_continue;
                }],
        );
        $exp->interact();
        $exp->soft_close();
    }
    exit unless ($opt_s);
}

sub ArrayToString() {
    my $string;
    my $array = $_[0];

    if (ref($array) eq 'ARRAY') {
        foreach my $val (@$array) {
            $string .= "\n\t" . $val;
        }
        $string =~ s/ *$//;
        $string =~ s/^ //g;
        return $string;
    } else {
        return "\n\t" . $array;
    }
}

sub ck_valid_change {
    my $change = $_[0];
    my $char = $_[1];
    my @chars = ( 1 .. $char );
    my $yes = 0;
    foreach my $res (@chars) {
        $yes = 1 if ($res eq $change);
    }
    return $yes;
}

sub main::HELP_MESSAGE {
    print <<EOF;
Usage: cm [-s] [menu arg]
            -s - no exit
EOF
}

sub main::VERSION_MESSAGE {
            print "Connection Manager version $version\n";
}
-- 
ubuntu-ru mailing list
ubuntu-ru@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-ru

Дати відповідь електронним листом