获取并使用 Bash shell 中包含特殊字符的密码

Get and use a password with special characters in Bash shell

我在 bash shell 脚本中使用带有特殊字符(例如 $)的密码时遇到了一些麻烦。

我的 shell 脚本是:

read -s -p "Password : " bindDNPass
ldapadd -H ldap://localhost -x -w $bindDNPass -D "dn=cn=Admin" -f /tmp/file.ldif

密码可能类似于 $Something18$。

嗯,命令

ldapadd -H ldap://localhost -x -W -D "dn=cn=Admin" -f /tmp/file.ldif` 

请求我的 $Something18$,并且工作正常。

但如果我尝试

ldapadd -H ldap://localhost -x -w $Something18$ -D "dn=cn=Admin" -f /tmp/file.ldif

没用。我猜它正在尝试解析变量 $Something18, 所以我尝试使用 $Something18$$Something18$, \$Something18$、...但它一直在失败...

我该怎么办? (不更改我的密码...)

放在double-quotes中并转义$符号避免shell,

的特殊解释
ldapadd -H ldap://localhost -x -w "$Something18$" -D "dn=cn=Admin" -f /tmp/file.ldif

(或)[更推荐]

将其包含在 single-quote 中,让 shell 将其视为文字字符串而不展开,

ldapadd -H ldap://localhost -x -w '$Something18$' -D "dn=cn=Admin" -f /tmp/file.ldif

来自 man bash 页面,

Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, , \, and, when history expansion is enabled, !. The characters $ and retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or . A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.

我发现您阅读和使用密码的方式存在两个潜在问题:

  • 当您使用 read 命令 而没有 -r 选项时,它会尝试解释转义(反斜杠)序列,这可能会导致问题.
  • 当您使用一个变量 而没有 将其包装在 double-quotes 中时,它会尝试将值拆分为单独的单词,并尝试将任何通配符扩展为匹配文件名列表。这可能会导致 大量 混乱,因此您应该几乎总是 double-quote 变量引用。

解决这些潜在问题给出了这个脚本片段:

read -rs -p "Password : " bindDNPass
ldapadd -H ldap://localhost -x -w "$bindDNPass" -D "dn=cn=Admin" -f /tmp/file.ldif

...但是,虽然您应该执行这两个修改以使您的脚本更健壮,但它们都不会改变它处理密码的方式 $Something18$。事实上,当我用那个密码尝试你的原始片段时,它被正确地传递给了 ldapadd。如果您的实际密码中有一些其他特殊字符(或者您玩过 IFS 的值),这些可能会有所帮助;否则,还有其他事情发生。

如果在这些修复后您的密码仍然无效,请尝试将 set -x 放在 ldapadd 命令之前(然后 set +x ),这样它就会打印出实际传递的内容至 ldapadd。好吧,它会以一种可能令人困惑的形式打印它:它会打印 一个等效的命令 到实际正在执行的内容,这意味着它会添加引号 and/or 转义到根据需要输入密码参数,以便您可以 运行 该命令,它会做同样的事情。当我用 $Something18$ 尝试时,它打印出:

+ ldapadd -H ldap://localhost -x -w '$Something18$' -D dn=cn=Admin -f /tmp/file.ldif

...其中 single-quotes 表示直接传递其中的内容,不进行解析。它还可以打印以下任何等效命令:

+ ldapadd -H ldap://localhost -x -w $Something18$ -D dn=cn=Admin -f /tmp/file.ldif
+ ldapadd -H ldap://localhost -x -w "$Something18$" -D dn=cn=Admin -f /tmp/file.ldif
+ ldapadd -H ldap://localhost -x -w $'$Something18$' -D dn=cn=Admin -f /tmp/file.ldif

所以你必须获取它打印的内容,并弄清楚 bash 是如何解析的,以便弄清楚实际传递给 ldapadd 的内容。但至少它会给你一些关于实际发生的事情的信息。

哦,您可能会注意到 DN 参数不是 double-quoted。那是因为它不包含任何特殊字符,所以 double-quotes 没有做任何事情,所以它只是将它们关闭。