12

我有一个期望脚本,我需要登录到远程系统并执行命令。除了向 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"

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

谢谢

编辑 正如我所说。我已经尝试转义 $ 字符。但为了澄清,我在脚本启动时添加了密码的打印语句,以验证变量是否正确包含密码......这是更改:

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.
4

8 回答 8

8

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

实际密码:
Pas$word

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

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

但问题是如果密码未知,例如密码在加密文件中或必须作为用户输入。我一直在寻找这种我不知道密码在哪里以及有多少 $ sings 的情况。

于 2017-08-18T15:42:43.977 回答
7

尝试转义反斜杠,即

Pas$word

变成

Pas\\\$word

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

我如何在 Bash 脚本中将期望与 SFTP 一起使用的完整示例:

#!/bin/bash
host=mysftp.dmz
port=22
username=john

/usr/bin/expect <<EOF
set timeout -1
spawn sftp -C -oPort=$port $username@$host
expect "password:"
send "Pas\\\$word\r"
expect "sftp>"
send "get data.txt\r"
expect "sftp>"
send "bye\r"
EOF
于 2015-10-27T09:42:41.427 回答
4

我无法通过转义美元符号来完成这项工作。通过使用 \x 来指定美元符号的十六进制值,我确实很幸运。

设置密码“Pas\x24word”

于 2015-01-22T21:42:57.723 回答
2

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

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

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

于 2017-03-01T15:04:40.353 回答
1

我有一个类似的问题,我想在期望脚本中传递带有“$”的文件名,以下对我有用

filePath=$(echo -n $filePath | sed -e 's/\$/\\\$/g')
于 2017-07-18T19:21:16.127 回答
1

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

send \"Pas\\\$word\"
于 2017-12-12T00:18:14.470 回答
-1

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

$ PASS="pa\$\$word"; somecommand --user unname --password $PASS

注意双引号和分号。

于 2013-08-14T22:08:36.257 回答
-1

这绝对应该有帮助 -

set username root
set password Pas\$word

摆脱引号。

希望这可以帮助。

于 2013-07-29T17:09:11.757 回答