Bash

將包含 $!@`’ 等特殊字元的密碼讀入 Bash 腳本的最佳實踐

  • July 16, 2020

我正在嘗試從stdinBash 腳本中的變數中讀取密碼。然後應該將此變數擴展為 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 絕對不可能完成,那麼我也對如何使用其他工具(乾淨且安全地)執行此操作的想法感興趣。

提前致謝

$ echo "$pw"
$!@`',

$ echo "${pw@Q}"
'$!@`'\'','

那應該這樣做。不過,我不知道bash這是在哪個版本中引入的。這也有效,並且可能更早可用:

$ printf %q "$pw"
\$\!@\`\'\,
# or, avoiding the command substitution
$ printf -v pw_ql1 %q "$pw"
$ echo "$pw_ql1"

幾種可能的解決方案。

  • 讓 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)"

引用自:https://unix.stackexchange.com/questions/598582