发送新密码后,我一直收到错误消息。它将更改密码,但不会更改脚本的其余部分。任何想法为什么它一直错误。我为不同的设备编写了一个非常相似的脚本并且它工作正常,但是在该设备上不需要更改密码后的内容。如果其余部分未完成,此设备将在重启后不保存密码。通过ssh手动完成它可以正常工作,因此不是cmds就是问题,这是脚本的内容。
#!/usr/bin/expect
set timeout -1
#Edit for User
set user user
#Edit for Old Password
set old oldpassword
#Edit for New Password
set new newpassword
#get IP List from iplist.txt
set f [open "/iplist.txt"]
set data [read $f]
close $f
foreach line [split $data \n] {
if {$line eq {}} continue
spawn ssh $user@$line
expect "assword:"
send "$old\r"
sleep 10
send "passwd $user\r"
expect "assword:"
send "$new\r"
expect "assword:"
send "$new\r"
sleep 10
send "grep -v users.1.password= /tmp/system.cfg > /tmp/system.cfg.new\r"
sleep 10
send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print \$2}'` >> /tmp/system.cfg.new\r"
sleep 10
send "cp /tmp/system.cfg.new /tmp/system.cfg\r"
sleep 10
send "save && reboot\r"
close
expect eof
}
如果设备没有响应ssh或原始密码错误,则完整脚本会因故障保险程序而变得更大。直到我弄清楚这一部分有什么问题,那个人才会工作。我只是把它缩小以找出问题发生的地方。此行似乎也是问题,因为它在它之前的行上创建了system.config.new:
send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print \$2}'` >> /tmp/system.cfg.new\r"
这是和ssh一样工作:
send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print $2}'` >> /tmp/system.cfg.new\r"
但由于$ 2发送错误,因此可以预期查看。我被告知放一个\ $ 2会使它只能查看远程shell。任何帮助都会很棒。
最初它曾期望“明星”而不是睡眠cmds。我已经在这个脚本上尝试了很多东西,一旦我把它运行在我的完整脚本中。我使用睡眠的原因是因为“star”似乎与输出不匹配并且在第二次发送$ new / r时失败。随着睡眠,它已经使它变得更远。我确实有一个纠正。它实际上正在发送“save&& reboot \ r \ n”。我将最终使用我的其他问题的$ prompt提示代替睡眠或期望“明星”。使用debug就可以抛出错误:
send: sending "save && reboot\r" to { exp4 }
expect: spawn id exp4 not open
while executing
"expect eof"
("foreach" body line 21)
invoked from within
"foreach line [split $data \n] {
if {$line eq {}} continue
spawn ssh $user@$line
expect "assword:"
send "$old\r"
sleep 3
send "passwd $user\r"
e..."
(file "./ubnt.sh" line 15)
“save&& reboot \ r \ n”将在保存设置后启动ssh连接,但似乎没有那么远。和&&有问题,也许我需要/&&。
答案 0 :(得分:0)
Interact而不是close并且期望eof是我完成时将使用完整脚本更新的答案。这是工作的UBNT密码更改脚本:
#!/usr/bin/expect
set timeout 30
#Edit for User
set user user
#Edit for Old Password
set old oldpassword
#Edit for New Password
set new newpassword
#get IP List from iplist.txt
set f [open "/iplist.txt"]
set data [read $f]
close $f
foreach line [split $data \n] {
if {$line eq {}} continue
spawn ssh $user@$line
expect {
"assword:" {
send "$old\r"
expect {
"assword:" {
close
continue
}}
expect {
"*" {
send "passwd $user\r"
expect "*assword:*"
send "$new\r"
expect "*assword:*"
send "$new\r"
expect "*"
send "grep -v users.1.password= /tmp/system.cfg > /tmp/system.cfg.new\r"
expect "*"
send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print \$2}'` >> /tmp/system.cfg.new\r"
expect "*"
send "cp /tmp/system.cfg.new /tmp/system.cfg\r"
expect "*"
send "save && reboot\r"
interact
continue
}}}}
expect {
"*" {
close
continue
}}
expect eof
}
以下是Mikrotik密码的脚本:
#!/usr/bin/expect
set timeout 30
#Edit for User
set user user
#Edit for Old Password
set old oldpassword
#Edit for New Password
set new newpassword
#get IP List from iplist.txt
set f [open "/iplist.txt"]
set data [read $f]
close $f
foreach line [split $data \n] {
if {$line eq {}} continue
spawn -noecho ssh -q -o "StrictHostKeyChecking=no" $user@$line
expect {
"assword:" {
send "$old\r"
expect {
"assword:" {
close
continue
}}
expect {
"*" {
send "user set $user password=$new\r"
expect ">"
send "quit\r"
close
continue
}}}}
expect {
"*" {
close
continue
}}
expect eof
}
Dinesh提到我不应该在我的expect命令中使用“star”,而是说使用:
set prompt "#|%|>|\\\$ $"
和
expect -re $prompt
我可能会改变。如果无法通过ssh访问设备或者旧密码不适用于设备,则脚本也会移至列表中的下一个IP。我计划在两者上进行的唯一其他更改是创建3个日志文件,列出成功的ips,错误的密码ips,以及无法达到ips。在每次继续之前,这应该只是一个命令,但还没有研究如何将变量输出到本地日志文件。
感谢您对Dinesh的帮助。