为什么应该避免在 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 函数,用户能够完全绕过脚本的预期功能。如果用户将像 rm *.* 这样的命令作为脚本参数传递,这可能会变得危险。
eval 的替代方案
由于上述影响,有一些可用的 eval 替代方案,可以使用它们,不会造成这样的安全威胁。
使用 token_quote 使 eval 更安全。
广告