簡體   English   中英

SSH 的 Bash/Expect 腳本

[英]Bash/Expect Script for SSH

我是 Expect 和一般腳本的新手。 我正在嘗試制作一些腳本,以便在拉取網絡設備配置時讓我的生活更輕松。 我設法將 SSH 的基本 Expect 腳本創建到設備並保存配置。

我想對此進行擴展,並允許腳本連接到多個 IP 地址,而不是像我現在這樣的一個地址。 我有一個名為list.txt的文件,其中包含幾個不同的 IP 地址,每個 IP 地址位於單獨的行上。

我需要做什么才能讓 Expect 腳本連接到每個 IP 地址並執行腳本中任務的 rest?

這是我到目前為止的 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 地址/主機變量,然后讀取下一行並重復?

我會這樣做(未經測試):

#!/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

注意事項:

  • 為簡潔起見,我刪除了您的所有評論
  • 使用\\r模擬send命令時按 Enter 鍵。
  • 我假設您只想記錄“show config running”輸出
  • 發送“退出”后使用expect eof

這是針對此問題的 Perl 版本:

安裝說明:

cpan Expect

這個腳本非常適合我的需要。

參數 1:連接字符串(例如:admin@10.34.123.10)
參數2:明文密碼
參數 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();

一種可能性是將 IP 地址作為參數傳遞到您的 Expect 腳本中:

set host_ip [lindex $argv 0]

然后制作一個 shell 腳本,在while循環中調用您的 Expect 腳本:

ips_file="list.txt"

while read line
do
    your_expect_script line
done < $ips_file

或者使用set ip [gets stdin]到用戶輸入的 IP 地址。

例如,

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

spawn使用它。 我們可以使用循環對多個 IP 地址執行相同的操作 -

spawn ssh $ip -l admin

這是將 expect 與 bash 集成的好方法:

ssh_util.expect-

#!/usr/bin/expect

set timeout -1
set ip   [lindex $argv 0]
set user [lindex $argv 1]
set pwd  [lindex $argv 2]
set commands [lrange $argv 3 [llength $argv]]

spawn ssh -o LogLevel=QUIET -t $user@$ip $commands

expect {
    yes/no       {send "yes\r" ; exp_continue}
    *?assword    {send "$pwd\r" ; exp_continue}
}

您可以使用./ssh_util.expect <commands...> 在終端中運行它。 在您的 shell 腳本中,您可以使用它在主機上運行命令,如下所示:

例子.sh -

#! /bin/bash

# ssh_exp <commands...>
ssh_exp () {
    ./ssh_util.expect 192.168.1.4 username password $*
}

# run commands on host machine here
ssh_exp ls
ssh_exp ls -la
ssh_exp echo "Echo from host machine"

# you can even run sudo commands (if sudo password is same as user password)
ssh_exp sudo apt install 

確保運行

chmod +x ssh_util.expect
chmod +x example.sh

在終端中使兩個文件都可執行。 希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM