相关文章推荐
英勇无比的脸盆  ·  mysql REGEXP ...·  1 周前    · 
活泼的弓箭  ·  python的subprocess模块 - ...·  1 年前    · 

在Bash shell中获取并使用带有特殊字符的密码

3 人关注

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

My shell script is :

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$,并且工作正常。

But if I try

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

它不起作用。我猜它试图解决变量$Something18,,所以我试着用\$Something18$\$Something18\$,来解决\\\$Something18$,......但它一直在失败......

我怎样才能做到呢?(不改变我的密码......)

2 个评论
Fred
为了确保我理解你的问题,是你的脚本失败了,你想让它工作,还是你的手动语句,还是两者都是?
嗯...最后,这个解决方案起作用了,但没有解决我的问题。我的意思是说,要在linux中允许有特殊字符的密码,它是有效的。但如果你用的是OpenDJ,就不行了。我最后安装了OpenLDAP,现在一切都好了。我不知道他们对ldaputilities的实现做了什么,让它在使用这样的密码时失败 :(
linux
bash
shell
quoting
Cheloute
Cheloute
发布于 2017-01-22
2 个回答
Inian
Inian
发布于 2017-01-22
已采纳
0 人赞同

把它放在双引号中,并转义为 $ 符号,以避免对 shell 的特殊解释。

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

(or) [more recommended]

把它放在单引号中,让shell把它当作一个字面字符串,而不去扩展它。

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

来自man bash页面。

将字符放在双引号内,可以保留引号内所有字符的字面价值, with the 除了$, , , 和, 当启用历史扩展时, ! 启用历史扩展时,还有!。 字符 字符$和保留其在双引号中的特殊含义. The 反斜杠只有在后面跟了以下字符时才有特殊意义:$, `, ", \, 或 .双引号可以在双引号内引出,前面加反斜杠。如果启用,将执行历史扩展,除非双引号中出现的!用反斜杠转义。在!前面的反斜杠不会被删除。

单引号是最好的,因为它不需要单独转义 $ 。转义最后的 $ 是可选的,因为没有后续字符来触发参数扩展。
Gordon Davisson
Gordon Davisson
发布于 2017-01-22
0 人赞同

我看到你在阅读和使用密码的方式上有两个潜在问题。

  • When you use the read command without the -r option, it'll try to interpret escape (backslash) sequences, which may cause trouble.
  • When you use a variable without wrapping it in double-quotes, it'll try to split the value into separate words and also try to expand any wildcards into a list of matching filenames. This can cause massive confusion, so you should almost always double-quote variable references.
  • 修复这些潜在的问题,可以得到这个脚本片段。

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

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

    如果你的密码在这些修正之后仍然不工作,可以尝试在ldapadd命令之前(和set +x之后)加入set -x,这样它就会打印出实际传递给ldapadd的内容。好吧,它将以一种可能令人困惑的形式打印:它将打印相等的命令这意味着它将在必要时为密码参数添加引号和/或转义,这样你可以运行该命令,它将做同样的事情。当我用$Something18$尝试时,它打印了。

    + 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
    + ldapadd -H ldap://localhost -x -w $'$Something18$' -D dn=cn=Admin -f /tmp/file.ldif