# Using Eval

suggest change

For example, consider the following that sets the contents of `\$@` to the contents of a given variable:

``````a=(1 2 3)
eval set -- "\${a[@]}"``````

This code is often accompanied by `getopt` or `getopts` to set `\$@` to the output of the aforementioned option parsers, however, you can also use it to create a simple `pop` function that can operate on variables silently and directly without having to store the result to the original variable:

``````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
}``````