【问题标题】:Bash/Expect Script for SSHSSH 的 Bash/Expect 脚本
【发布时间】:2020-06-25 03:37:09
【问题描述】:

我是 Expect 和一般脚本的新手。我正在尝试制作一些脚本,以便在提取网络设备配置时让我的生活更轻松。我设法创建了一个基本的 Expect 脚本以通过 SSH 连接到设备并保存配置。

我想对此进行扩展,并允许脚本连接到多个 IP 地址,而不是像我现在这样的一个。我有一个名为 list.txt 的文件,其中包含几个不同的 IP 地址,每个 IP 地址位于单独的一行。

我需要做什么才能让 Expect 脚本连接到每个 IP 地址并同时执行脚本中的其余任务?

这是我目前拥有的 Expect 脚本:

#!/usr/bin/expect -f
# Tells interpreter where the expect program is located.  This may need adjusting according to
# your specific environment.  Type ' which expect ' (without quotes) at a command prompt
# to find where it is located on your system and adjust the following line accordingly.
#
#
# Use the built in telnet program to connect to an IP and port number
spawn ssh 192.168.1.4 -l admin
#
# The first thing we should see is a User Name prompt
#expect "login as:"
#
# Send a valid username to the device
#send "admin"
#
# The next thing we should see is a Password prompt
expect "Password:"
#
# Send a valid password to the device
send "password\n"
#
# If the device automatically assigns us to a privileged level after successful logon,
# then we should be at an enable prompt
expect "Last login:"
#
# Tell the device to turn off paging
#
# After each command issued at the enable prompt, we expect the enable prompt again to tell us the
# command has executed and is ready for another command
expect "admin@"
#
# Turn off the paging
send "set cli pager off\n"
#
# Show us the running configuration on the screen
send "show config running\n"
#
# Set the date.
set date [timestamp -format %C%y%m%d]
#
# Test output sent to file with a timestamp on end
#-noappend will create a new file if one already exists
log_file -noappend /home/test.cfg$date
#
expect "admin@"
#
# Exit out of the network device
send "exit\n"
#
# The interact command is part of the expect script, which tells the script to hand off control to the user.
# This will allow you to continue to stay in the device for issuing future commands, instead of just closing
# the session after finishing running all the commands.`enter code here`
interact

我需要将它与 Bash 脚本集成吗?如果是这样,是否可以读取 list.txt 文件的一行,将其用作 IP 地址/主机变量,然后读取下一行并重复?

【问题讨论】:

  • 您可以将您的设备配置为使用 ssh 密钥吗?如果是,您根本不需要期望。

标签: bash ssh expect


【解决方案1】:

我会这样做(未经测试):

#!/usr/bin/expect -f

set logfile "/home/text.cfg[clock format [clock seconds] -format %Y%m%d]"
close [open $logfile w]         ;# truncate the logfile if it exists

set ip_file "list.txt"
set fid [open $ip_file r]

while {[gets $fid ip] != -1} {

    spawn ssh $ip -l admin
    expect "Password:"
    send "password\r"

    expect "admin@"
    send "set cli pager off\r"

    log_file $logfile
    send "show config running\r"

    expect "admin@"
    log_file 

    send "exit\r"
    expect eof

}
close $fid

注意事项:

  • 为简洁起见,我删除了你所有的 cmets
  • 使用\r 模拟您在send 命令时按回车。
  • 我假设您只想记录“显示配置运行”输出
  • 发送“退出”后使用expect eof

【讨论】:

    【解决方案2】:

    这是针对此问题的 Perl 版本:

    安装说明:

    cpan Expect
    

    这个脚本非常适合我的需要。

    参数一:连接字符串(例:admin@10.34.123.10)
    参数二:明文密码
    参数3:要执行的命令

    #!/usr/bin/perl
    use strict;
    
    use Expect;
    
    my $timeout = 1;
    
    my $command = "ssh " . $ARGV[0] . " " . $ARGV[2];
    
    #print " => $command\n";
    
    my $exp = Expect->spawn($command) or die "Cannot spawn $command: $!\n";
    $exp->raw_pty(1);
    
    LOGIN:
    $exp->expect($timeout,
            [ 'ogin: $' => sub {
                         $exp->send("luser\n");
                         exp_continue;
                    }
            ],
            [ 'yes\/no\)\?\s*$' => sub {
                        $exp->send("yes\n");
                        goto LOGIN;
                    }
            ],
            [ 'assword:\s*$' => sub {
                        $exp->send($ARGV[1]."\n");
                        #print "password send: ", $ARGV[1];
                        exp_continue;
                    }
            ],
            '-re', qr'[#>:] $'
    );
    $exp->soft_close();
    

    【讨论】:

      【解决方案3】:

      一种可能性是在您的 Expect 脚本中将 IP 地址作为参数传递:

      set host_ip [lindex $argv 0]
      

      然后制作一个 shell 脚本,在 while 循环中调用您的 Expect 脚本:

      ips_file="list.txt"
      
      while read line
      do
          your_expect_script line
      done < $ips_file
      

      【讨论】:

        【解决方案4】:

        或者使用set ip [gets stdin]从用户输入的IP地址。

        例如,

        puts "Enter your IP address\n"
        set ip [get stdin]
        

        spawn 中使用它。我们可以使用循环对多个 IP 地址执行相同的操作 -

        spawn ssh $ip -l admin
        

        【讨论】:

        • 欢迎来到 Stackoverflow。你介意扩大你的答案来解释它是如何解决问题的吗?
        猜你喜欢
        • 2016-01-06
        • 1970-01-01
        • 2011-06-14
        • 1970-01-01
        • 2022-10-19
        • 2016-09-20
        • 1970-01-01
        相关资源
        最近更新 更多