Вот самая простая дистиллированная версия моей проблемы. Сложность, которая остается, имеет веские причины, даже если здесь она не очевидна. Кроме того, скрипт является внутренним и не имеет возможности выполнить вредоносный код, поэтому eval работает отлично; не нужно слышать о том, насколько это зло... ;) Предположим на данный момент, что вертикальные черты и двоеточия в ключевой строке являются обязательными разделителями.
key="target|platform|repo:revision"
hashname="hashmap"
declare -A $hashname
eval $hashname[$key]=0
echo $(eval $hashname[$key])
Конечно, последние две строки имеют проблемы, потому что eval работает с каналами и двоеточиями внутри переменной $key. Мой вопрос: как я могу защитить такую строку от eval? И мне нужен eval, потому что я имею в виду имя хэш-карты, а не ее саму. Заранее спасибо.
==================================================================================
Хорошо, я на самом деле начинаю думать, что моя проблема не в каналах, двоеточии и eval. Итак, позвольте мне вставить настоящий код
function print_hashmap()
{
local hashname=$1
for key in `eval echo \$\{\!$hashname[@]\}`; do
local deref="$hashname[$key]"
local value=${!deref}
echo "key=${key} value=${value}"
done
}
function create_permutations2()
{
local hashname=$1 ; shift
local builds=$1 ; shift
local items=$1 ; shift
local separators=$@
echo "create_permutations(hashname=${hashname}, builds=${builds}, items=${items}, separators=${separators})"
if [ NULL != "${builds}" ]; then
for build in `echo $builds | tr ',' ' '`; do
local target="${build%%:*}"
local platforms="${build##*:}"
for platform in `echo $platforms | tr '|' ' '`; do
local key=
local ref=
if [ NULL != "${items}" ]; then
if [ NULL == "${separators}" ]; then separators=' '; fi
for separator in $separators; do
items=`echo $items | tr $separator ' '`
done
for item in $items; do
key="${target}|${platform}|${item}"
ref="$hashname[$key]"
declare "$ref"=0
done
else
key="${target}|${platform}"
ref="$hashname[$key]"
declare "$ref"=0
fi
done
done
fi
echo "created the following permutations:"
print_hashmap $hashname
}
builds="k:r|s|w,l:r|s|w"
repos="c:master,m:master"
hashname="hashmap"
declare -A $hashname
create_permutations2 $hashname $builds $repos ","
print_hashmap $hashname
Недавно я изменил свой код, чтобы он соответствовал предложениям FatalError по использованию ref вместо eval, и ошибка та же самая: синтаксическая ошибка в выражении (маркер ошибки рядом с: master)
\|
вместо|
- person Gigi   schedule 05.02.2012{}
- person Kevin   schedule 06.02.2012eval
в подоболочке попытается выполнить0
, если он сработает. - person Kevin   schedule 06.02.2012