为什么在Bash中应该避免eval,我应该用什么来代替呢?
eval是Bashshell的内置命令,它将其参数连接为单个字符串。然后,它将参数与空格连接起来,然后将该字符串作为bash命令执行。以下是其工作方式的示例。
eval示例
在下面的示例中,我们使用一个字符串,该字符串中内置了一些Unix命令,然后对其应用eval。
$ var="echo n" $ echo $var $ eval $var
运行上面的代码给我们以下结果-
echo n n
如您所见,当应用eval时,变量展开,它将作为命令执行,而不再只是字符串。
eval问题
当我们创建一些包含函数的变量或脚本时,可以将一些值推入可能具有潜在危险的变量或函数。例如,可以将删除文件命令传递到接受用户参数的脚本。脚本的所有者将具有删除文件特权,但调用脚本的用户则没有。
考虑下面的脚本,我们在其中调用一个函数,其中包含一个eval函数。
Printa_rray() { in_array=$1 eval echo "\"The first vale in the array is \${$in_array[0]}\"" } fruits=(apple, orange, grapes,berry) print_array fruits
运行上面的代码给我们以下结果-
The first vale in the array is apple.
以上结果是预期的。但是,假设用户使用以下参数调用该函数。
print_array() { in_array=$1 eval echo "\"The first vale in the array is \${$in_array[0]}\"" } fruits=(apple, orange, grapes,berry) print_array 'x}"; cal; #'
运行上面的代码给我们以下结果-
The first vale in the array is December 2019 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
如您所见,由于脚本中存在eval函数,因此使用该函数能够完全绕过acript的预期功能。如果用户将诸如rm*。*之类的命令作为acript参数传递,则可能会很危险。
eval替代
由于上述含义,因此可以使用一些可用的替代方法,这些替代方法不会造成此类安全威胁。
使用token_quote可以使男性评估更安全。