eval
を使用すると、任意のコードの実行が可能になるため、お勧めできません。ただし、eval echo
の場合、残りの文字列はecho
の引数になるため、安全である必要があります。これは正しいですか?
反例:
DANGEROUS=">foo"
eval echo $DANGEROUS
echo
への任意の引数は、 "foo"と呼ばれるファイルを作成するよりも悪質なことをした可能性があります。
@Celadaは素晴らしい答えを提供してくれました。 eval
が本当に悪であることを示すために、ここに"foo"というファイルを作成するよりも悪質なものを示します。
DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"
そしてもちろん"foo"と呼ばれるファイルを作成するよりも悪質なものよりも悪質なものが存在する可能性があります。
いいえ、それはnotは常に安全です。 evalは任意のコマンドを実行できます。
次のような安全なコマンド(単一引用符内にあるため、日付は実行されません):
$ echo '$(date)'
$(date)
Evalと一緒に使用すると危険になります:
$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016
もちろん、日付はanyコマンドにすることもできます。
これを改善する1つの方法は、evalの引数をさらに引用することです。
$ eval echo '\$(date)'
$(date)
ただし、式を2回正しく引用することは通常困難です。
また、次のように外部の攻撃者が式を設定した場合、正しい引用を制御できなくなります。
$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!
eval
には常に注意が必要ですが、eval echo
構築は必ずしも無意味であるとは限らず、canを安全に使用できます。最近、複数のブレース展開を必要な順序で評価するために必要でした。
bash
は、左から右へ複数のブレース展開を行うので、
xargs -I_ cat _/{11..15}/{8..5}.jpg
に拡大する
xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg
しかし、私は最初に行われる2番目のブレースの拡張が必要でした。
xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg
それをするために私が思いつくことができた最高のものは
xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)
これは、単一引用符がeval
コマンドラインの解析中に最初の中括弧のセットを展開から保護し、eval
によって呼び出されたサブシェルによって展開されるため、機能します。
ネストされたブレース展開を含むいくつかの狡猾なスキームがあるかもしれませんが、これを1つのステップで行うことができます。 bash
以外にも、この種のことを実現するための整然とした方法を可能にするシェルがあります。ただし、いずれの場合でも、eval
の使用は安全です。その引数はすべて、パラメータ展開を含まない固定文字列だからです。