Bash
いつevalを使うか
サーチ…
前書き
まず第一に、あなたがやっていることを知ってください!第二に、 eval
使用を避けるべきですが、より洗練されたコードを使用する場合は、先に進んでください。
評価を使用する
たとえば、 $@
の内容を指定された変数の内容に設定する次のことを考えてみましょう。
a=(1 2 3)
eval set -- "${a[@]}"
このコードでは、前述のオプションパーサーの出力に$@
を設定するためにgetopt
またはgetopts
が付いていることがよくありますが、これを使用して、結果を格納せずに静かに直接変数を操作できる単純なpop
関数を作成することもできます元の変数:
isnum()
{
# is argument an integer?
local re='^[0-9]+$'
if [[ -n $1 ]]; then
[[ $1 =~ $re ]] && return 0
return 1
else
return 2
fi
}
isvar()
{
if isnum "$1"; then
return 1
fi
local arr="$(eval eval -- echo -n "\$$1")"
if [[ -n ${arr[@]} ]]; then
return 0
fi
return 1
}
pop()
{
if [[ -z $@ ]]; then
return 1
fi
local var=
local isvar=0
local arr=()
if isvar "$1"; then # let's check to see if this is a variable or just a bare array
var="$1"
isvar=1
arr=($(eval eval -- echo -n "\${$1[@]}")) # if it is a var, get its contents
else
arr=($@)
fi
# we need to reverse the contents of $@ so that we can shift
# the last element into nothingness
arr=($(awk <<<"${arr[@]}" '{ for (i=NF; i>1; --i) printf("%s ",$i); print $1; }'
# set $@ to ${arr[@]} so that we can run shift against it.
eval set -- "${arr[@]}"
shift # remove the last element
# put the array back to its original order
arr=($(awk <<<"$@" '{ for (i=NF; i>1; --i) printf("%s ",$i); print $1; }'
# echo the contents for the benefit of users and for bare arrays
echo "${arr[@]}"
if ((isvar)); then
# set the contents of the original var to the new modified array
eval -- "$var=(${arr[@]})"
fi
}
GetoptでEvalを使う
pop
様の関数ではevalは必要ないかもしれませんが、 getopt
を使うときはいつでも必要です:
-h
をオプションとして受け入れる次の関数を考えてみましょう。
f()
{
local __me__="${FUNCNAME[0]}"
local argv="$(getopt -o 'h' -n $__me__ -- "$@")"
eval set -- "$argv"
while :; do
case "$1" in
-h)
echo "LOLOLOLOL"
return 0
;;
--)
shift
break
;;
done
echo "$@"
}
eval
set -- "$argv"
なしset -- "$argv"
は、目的の(-h --)
代わりに-h --
生成し、その後-h --
が--
または-h
一致しないため無限ループに入ります。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow