运行 base64 编码的 bash 脚本给我错误

运行 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

我不知道要解决这个问题。

答案1

运行它以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 ... | bashshell 运行的脚本也来自标准输入。因此,read尽职尽责地读取输入流中的下一行,即带有 的行randint=...,并将其放入变量中n......

(当然,*$n是分词为多个参数,因为$n没有引用。)

您需要安排脚本从不同的文件描述符进入,例如使用进程替换将脚本传递到 shell(在 Bash/ksh/zsh 中):

bash <( base64 -d <<< "$exec" )

或者通过read从其他 fd 读取,例如通过将输入重定向到readfrom直接从终端读取/dev/tty。使用几乎一行进行测试(单引号字符串延续到第二行):

$ printf 'read -r -p "say something: " foo < /dev/tty; 
          echo "you entered: $foo"' | bash
say something: asdfsadf
you entered: asdfsadf

话又说回来,您可能会考虑仅将输入数据作为命令行参数传递,而不是以交互方式请求它。命令行参数更容易编写脚本,并且直接读取终端也特别令人讨厌,正是因为它阻止了轻松使用脚本来提供程序。

另请注意,这不是标准 shell 功能,因此您可能应该使用(or 、 or ) 而不是RANDOM显式运行脚本。bashkshzshsh

相关内容