期望脚本出错

时间:2016-03-06 15:03:42

标签: ssh scripting expect

发送新密码后,我一直收到错误消息。它将更改密码,但不会更改脚本的其余部分。任何想法为什么它一直错误。我为不同的设备编写了一个非常相似的脚本并且它工作正常,但是在该设备上不需要更改密码后的内容。如果其余部分未完成,此设备将在重启后不保存密码。通过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连接,但似乎没有那么远。和&&有问题,也许我需要/&&。

1 个答案:

答案 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的帮助。