Shell-Script
執行 base64 編碼的 bash 腳本給我錯誤
我有一個 bash 腳本;該腳本是生成一個隨機數並讓使用者猜測它。
printf 'Guess the number (1-10) : ' read -r n randint=$(( ( RANDOM % 10 ) + 1 )) if [ $n = $randint ]; then echo "You Won !" else echo "Sorry, try again !" fi
它可以工作,但在下一個腳本中,我將此程式碼編碼為 base64 並嘗試使用以下程式碼執行它。
exec="cHJpbnRmICdHdWVzcyB0aGUgbnVtYmVyICgxLTEwKSA6ICcKcmVhZCAtciBuCnJhbmRpbnQ9JCgoICggUkFORE9NICUgMTAgKSAgKyAxICkpCgppZiBbICRuID0gJHJhbmRpbnQgXTsKdGhlbgplY2hvICJZb3UgV29uICEiCmVsc2UKZWNobyAiU29ycnksIHRyeSBhZ2FpbiAhIgpmaQ==" base64 -d <<< $exec | sh
它在 Cygwin 終端中給出了這個錯誤:
Guess the number (1-10) : sh: line 4: [: too many arguments Sorry, try again !
我嘗試了一個線上編譯器,但它也失敗了:
sh: 5: [: =: unexpected operator
我不知道要解決這個問題。
執行它
set -x
以查看 shell 實際執行的內容,命令顯示在以 開頭的行中+
:+ printf 'Guess the number (1-10) : ' Guess the number (1-10) : + read -r n + '[' 'randint=$((' '(' RANDOM % 10 ')' + 1 '))' = ']' bash: line 4: [: too many arguments [...]
什麼是測試,裡面
[ ... ]
,作業randint=...
(*)?它應該是read n
給予的。它應該向使用者詢問號碼,但沒有?嗯,事情就是這樣,
read
從標準輸入讀取,在管道base64 ... | bash
中,shell 執行的腳本也來自標準輸入。因此,read
盡職盡責地讀取輸入流中的下一行,即帶有randint=...
, 的行,並將其放入變數n
…(*
$n
被分詞成多個參數,當然,因為$n
沒有被引用。)您需要安排腳本從不同的文件描述符進入,例如使用程序替換將腳本傳遞給 shell(在 Bash/ksh/zsh 中):
bash <( base64 -d <<< "$exec" )
或者通過
read
從其他一些 fd 讀取,例如通過將輸入重定向到read
from直接從終端讀取/dev/tty
。使用幾乎單行進行測試(單引號字元串繼續到第二行):$ printf 'read -r -p "say something: " foo < /dev/tty; echo "you entered: $foo"' | bash say something: asdfsadf you entered: asdfsadf
再說一次,您可能會考慮只將輸入數據作為命令行參數傳遞,而不是互動式地請求它。命令行參數更容易編寫腳本,直接讀取終端也特別令人討厭,正是因為它阻止了輕鬆使用腳本來提供程序。
另請注意,這
RANDOM
不是標準的 shell 功能,因此您可能應該使用bash
(或ksh
,或zsh
)顯式執行腳本,而不是sh
.