如何在Expect脚本中使用$符号发送密码

时间:2013-07-29 16:13:24

标签: bash authentication ssh expect remote-server

我有一个期望脚本,我需要登录到远程系统并执行命令。此脚本适用于向root帐户提供密码的例外。 root密码包含一个我似乎无法工作的美元符号。这是代码

#!/usr/bin/expect
set timeout 3
set username "root"
set password "Pas$word"
set hostname [lindex $argv 0]
log_user 0

send_user "\n#####\n# $hostname\n#####\n"

spawn ssh -q -o StrictHostKeyChecking=no $username@$hostname

expect {
    timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
    eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
    "*assword"
}

send "$password\r"

expect {
    timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
    "*\$ "
}

send_user "\nPassword is correct\n"

expect "$ " { send "ls" }

我在提供密码不包含美元符号的凭据时验证了这一点,但我无法使用root帐户。它总是产生Login failed. Password incorrect超时错误。无法更改密码。我试图在密码定义中提供\转义字符,如下所示:

set password "Pas\$word"

我得到了同样的结果......关于我做错了什么的任何想法?

由于

修改 就像我说的。我已经试图逃避$字符。但为了澄清,我在脚本启动时为密码添加了一个print语句,以验证变量是否正确包含密码......以下是更改:

set password "Pas\$word"
...
send_user "\n#####\n# $hostname\n#####\n"
send_user "Using password: $password\n"
...

这是控制台输出:

njozwiak@ubuntu:~$ ./ssh_ls.sh 192.168.5.93

#####
# 192.168.5.93
#####
Using password: Pas$word

Login failed. Password incorrect.

8 个答案:

答案 0 :(得分:5)

我找到了一个临时解决方案。我很确定很久以前就解决了这个问题,只提到我是如何解决的:

实际密码:
Pas$word

分配给变量密码:
set password {Pas\$word}

在TCL中(或在您的代码中期望),在双括号{}内对单词进行分组会禁用大括号内的替换,因此您的密码将存储为: Pas\$word
现在最后,当您通过expect Pas\$word发送密码时,将被翻译为Pas$word这是实际密码。

但问题是如果密码未知,例如,密码在加密文件中或必须作为用户输入。我正在寻找这种类型的案例,我不知道密码在哪里和多少美元唱歌。

答案 1 :(得分:3)

我无法通过逃避美元符号来实现这一目标。我确实很幸运,使用\ x指定美元符号的十六进制值。

设置密码“Pas \ x24word”

答案 2 :(得分:2)

尝试转义反斜杠,即

help p

变为

Pas$word

这是脚本(即使使用PHP,Python)的常见问题,其中字符串未转义两次甚至更多次!

我在Bash脚本中使用 expect 与SFTP的完整示例:

Pas\\\$word

答案 3 :(得分:0)

我发现这个问题是因为我有同样的问题,我知道这是一个老问题,但是对于那些仍在寻找快速解决方案的人来说:

set CorrectedPassword [ string map -nocase { "\$" "\\\$" } $MyPassword ]

然后登录过程接受$ CorrectedPassword。不需要-nocase,但我发现默认包含它更安全。

答案 4 :(得分:0)

我有一个类似的问题,我想用" $"传递fileName。在期待脚本和以下为我工作

filePath=$(echo -n $filePath | sed -e 's/\$/\\\$/g')

答案 5 :(得分:0)

我在下面使用它对我有用:

send \"Pas\\\$word\"

答案 6 :(得分:-1)

这绝对有帮助 -

set username root
set password Pas\$word

删掉引号。

希望这有帮助。

答案 7 :(得分:-1)

我最近遇到了类似的问题。这对我有用:

$ PASS =“pa \ $ \ $ word”; somecommand --user uname --password $ PASS

注意双引号和分号。