为什么在Bash中应该避免eval,我应该用什么来代替呢?

eval是Bash shell的内置命令,它将其参数连接为单个字符串。然后,它将参数与空格连接起来,然后将该字符串作为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可以使男性评估更安全。