stdin
我正在尝试从Bash 脚本中的变量中读取密码。然后应将该变量扩展为 ssh 命令并传输到服务器。在那里,密码应该以正确转义的方式到达,因此它可以用作另一个命令的输入。 (在本例中更改我的 pihole 的登录密码)。
目前我有类似的东西:
read -rs -p "Password: `echo $'\n> '`" newpass
ssh root@gate "pihole -a -p \"${newpass}\""
但也尝试过:
ssh root@gate "pihole -a -p ""'""${newpass}""'"
ssh root@gate 'pihole -a -p '"${newpass}"
ssh root@gate 'pihole -a -p '"${newpass}"''
ssh root@gate "pihole -a -p \'${newpass}\'"
ssh root@gate 'pihole -a -p ''\''"${newpass}"'\''
即使使用 printf:
IFS= read -rs -p "Password: `echo $'\n> '`" newpass
command=$(printf 'pihole -a -p %s\n' "$newpass")
或者
IFS= read -rs -p "Password: `echo $'\n> '`" newpass
command=$(printf 'pihole -a -p '\''%s'\''\n' "$newpass")
还有很多。但有了这个密码:a$#5!6k?h'v;z'
他们都失败了。而且里面甚至还没有反勾号……
我向所有 Bash 专家提出的问题是:
将密码解析为变量(用户可以在其中输入)的正确方法是什么字面上任何特点?
这包括:
$
!
` (backtick)
' (single quote)
"
;
#
@
\
/
~
\n
等等...
我已阅读此处和其他论坛中的所有相关问题,但找不到此用例的解决方案。
我知道,会有人建议使用 Python 或 C 或其他东西,但我仍然对 Bash 的功能感兴趣。
但是,如果使用 Bash 绝对不可能完成此任务,那么我也对如何使用其他工具(干净且安全地)完成此任务的想法感兴趣。
提前致谢
答案1
几种可能的解决方案。
让 pihole 直接询问密码,而不是使用您自己的提示符。
ssh -t user@host pihole -a -p
read
在目标端运行您自己的提示符:ssh -t user@host 'read -rsp "Password: " newpass && pihole -a -p "$newpass"'
将其通过管道:
echo "$newpass" | ssh user@host 'read -r newpass && pihole -a -p "$newpass"'
引用您在传递之前读取的密码:
read -rsp "Password: " newpass qnewpass=$(printf "%q" "$newpass") ssh user@host pihole -a -p "$qnewpass"
对密码进行编码并在另一侧对其进行解码:
newpass_base64=$(printf "%s" "$newpass" | base64) ssh user@host "pihole -a -p \$(echo $newpass_base64 | base64 -d)"
根本不要使用特殊字符,XKCD风格。 ;-)
答案2
$ echo "$pw"
$!@`',
$ echo "${pw@Q}"
'$!@`'\'','
应该可以做到这一点。但我不知道bash
这是在哪个版本中引入的。这也有效,并且可能更早可用:
$ printf %q "$pw"
\$\!@\`\'\,
# or, avoiding the command substitution
$ printf -v pw_ql1 %q "$pw"
$ echo "$pw_ql1"