防止 Expect 对远程 shell 命令的变量替换

Prevent Expect's variable substitution for a remote shell command

我需要 运行 这个带有 expect 脚本的命令:

    echo users.1.password=`grep %user% /etc/passwd | awk -F: '{print }'` >> /tmp/system.cfg.new

但是因为里面有$2所以出错了。我该如何解决?我需要变量只对我发送 cmd 的设备可见。

这是通过脚本在 UBNT 设备上更改密码的完整脚本(通过 ssh 工作,但由于 $2 而不是脚本):

    #!/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 }'` >> /tmp/system.cfg.new\r"
                                            expect "*"
                                            send "cp /tmp/system.cfg.new /tmp/system.cfg\r"
                                            expect "*"
                                            send "save && reboot\r"
                                            close
                                            continue
                                            }}}}
            expect {
                    "*" {
                            close
                            continue
                            }}
            expect eof
     }

你只需要用反斜杠转义美元符号。

send "echo users.1.password=`grep $user /etc/passwd | awk -F: '{print $2}'` >> /tmp/system.cfg.new\r"

顺便说一句,使用 expect * 可能是 dangerous,除非阅读需要,否则不推荐使用。

您可以使用通用方法来匹配提示,

set prompt "#|%|>|\$ $"

在这里,我们用反斜杠转义了文字美元符号,最后一个美元用于行尾正则表达式。

向远程发送任何命令后 shell,您可以 expect 将模式设置为

expect -re $prompt