為什麼應該避免在 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 更安全。

更新於: 2020年1月3日

1K+ 閱讀量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.