获取并使用 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 没有做任何事情,所以它只是将它们关闭。
我在 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 没有做任何事情,所以它只是将它们关闭。