bash 如何在 Expect Script 中发送带有 $ 符号的密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17928947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:59:25  来源:igfitidea点击:

How to send a password with a $ symbol in Expect Script

bashauthenticationsshexpectremote-server

提问by linsek

I have an expect script that I need to login to a remote system and execute commands. This script works with the exception of providing the password to the root account. The root password contains a dollar sign that I cannot seem to get to work. Here is the code

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

I have verified this works when providing credentials whose passwords don't contain the dollar sign, but I can't get it to work with the root account. It always produces the Login failed. Password incorrecttimeout error. Changing the password is not an option. I have tried to supply the \escape character in the password definition like so:

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

set password "Pas$word"

And I get the same results... any ideas on what I'm doing wrong?

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

Thanks

谢谢

EDITAs I said. I already tried to escape the $ character. But to clarify, I added a print statement for the password when the script starts up to verify the variable contains the password correctly... Here is the change:

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

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

Here is the console output:

这是控制台输出:

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

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

Login failed. Password incorrect.

回答by Hasan Rumman

I've found a makeshift solution for this. I'm sure this problem solved long ago, just mentioning how I solved mine:

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

Actual password:
Pas$word

实际密码:
Pas$word

Assign to variable password:
set password {Pas\$word}

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

In TCL(or expect in your code), grouping words within double braces {} disables substitution within the braces, thus your password will be stored as: Pas\$word
Now in the end, when you send password via expect Pas\$wordwill be translated as Pas$wordwhich is the actual password.

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

But the problem is if the password is unknown, for example, password is in an encrypted file or has to be taken as user input. I was looking for this type of cases where I don't know where and how many $ sings are in the password.

但问题是如果密码未知,例如密码在加密文件中或必须作为用户输入。我正在寻找这种类型的情况,我不知道密码中的 $ 位置和数量。

回答by John Mayor

Try escaping the backslash, that is

尝试转义反斜杠,即

Pas$word

becomes

变成

Pas\$word

This is a common problem with scripting (even with PHP, Python) where a string gets unescaped twice or even more times!

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

A full-blown example how I use expectwith SFTP, inside a Bash script:

我如何在 Bash 脚本中将expect与 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

回答by Jonathan Crowe

I was unable to get this working by just escaping the dollar sign. I did have luck by using \x to specify the hex value for the dollar sign.

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

set password "Pas\x24word"

设置密码“Pas\x24word”

回答by Whatts

I found this question because I had the same issue, I know it's an old question but for whoever is also still looking for a quick solution:

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

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

The $CorrectedPassword is then accepted by the login procedure. The -nocase is not needed, but I find it safer to include by default.

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

回答by Vaibhav Fouzdar

I had a similar issue where I wanted to pass fileName with "$" in expect script and following worked for me

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

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

回答by Sky

I used below and it worked for me :

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

send \"Pas\\\$word\"

send \"Pas\\\$word\"

回答by SSaikia_JtheRocker

This should definitely help -

这绝对有帮助 -

set username root
set password Pas$word

Get rid of the quotes.

摆脱引号。

Hope this helps.

希望这可以帮助。

回答by wnet

I had a similar problem recently. This worked for me:

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

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

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

Notice double quotes and the semicolon.

注意双引号和分号。