私は一般的なスクリプト作成にかなり慣れていません。CiscoスイッチにSSH接続し、「showcdpneighbors」コマンドを実行してスイッチに接続されているすべてのデバイスのリストを取得するexpectスクリプトを作成しています。次に、出力を変数に保存して、sshセッションを終了します。含まれているファイルにユーザー名とパスワードを設定しています。
#!/usr/bin/expect -f
#exp_internal 1
source accountfile
set timeout 10
spawn $env(SHELL)
expect "#"
send "ssh $USERNAME@<hostname>\r"
expect {
"continue connecting" {
send_user "Adding host to ssh known hosts list...\n"
send "yes\n"
exp_continue
}
"Do you want to change the host key on disk" {
send_user "Changing host key on disk...\n"
send "yes\n"
exp_continue
}
"assword:" {
send "$PASSWORD\r"
}
}
expect "#"
send "term len 0\r"
expect "#"
send "show cdp neighbors\r"
expect "#"
set result $expect_out(buffer)
send "exit\r"
expect "#"
そこで、$ resultを取得して、「R」を含む行を探し、それらの行をファイルに保存します(両側にスペースがあるRはルーターを示し、これが私が興味を持っているものです)
問題は、接続されているデバイスの名前が長い場合、デバイスの名前が1行に表示され、デバイスに関する残りのデータが次の行に表示されることです。したがって、「R」文字列と一致すると、名前が前の行にあるため、デバイスの名前を取得できません。
Device ID Local Intrfce Holdtme Capability Platform Port ID
...
<device_name_really_long>
Gig 2/0/52 171 R S I WS-C6509 Gig 3/14
<device_name2> Gig 2/0/1 131 H P M IP Phone Port 1
...
何か案は?おそらくそれを行う正規表現があるでしょうが、私は正規表現についてスクワットを知りません。
解決済み:GlennJackmanに感謝します
バッファがいっぱいかどうかを確認するためにexpect条件を追加する必要があったため、最終的なコードは次のようになります。
#!/usr/bin/expect
#exp_internal 1
match_max 10000
set expect_out(buffer) {}
set timeout 30
source accountfile
spawn $env(SHELL)
expect "#"
send "ssh $USERNAME@ol2110-3750stack.sw.network.local\r"
expect {
"continue connecting" {
send_user "Adding host to ssh known hosts list...\n"
send "yes\n"
exp_continue
}
"Do you want to change the host key on disk" {
send_user "Changing host key on disk...\n"
send "yes\n"
exp_continue
}
"assword:" {
send "$PASSWORD\r"
}
}
expect "#"
send "term len 0\r"
expect "#"
send "show cdp neighbors\r"
set result ""
expect {
{full_buffer} {
puts "====== FULL BUFFER ======"
append result $expect_out(buffer)
exp_continue
}
"#" {
append result $expect_out(buffer)
}
}
send "exit\r"
expect "#"
set devices [list]
set current_device ""
set lines [split $result "\n"]
foreach line $lines {
set line [string trim $line]
if {[llength $line] == 1} {
set current_device $line
continue
}
set line "$current_device$line\n"
if {[string match {* R *} $line]} {
lappend devices $line
}
set current_device ""
}
puts $devices