Вы можете сделать это с помощью declare
вместо eval
, например:
Вместо:
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
echo "Initial string: $string"
eval 'for word in '$string'; do echo $word; done'
Делать:
declare -a "array=($string)"
for item in "${array[@]}"; do echo "[$item]"; done
Но обратите внимание, это не намного безопаснее, если ввод поступает от пользователя!
Итак, если вы попробуете это, скажем, строка вроде:
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo" `hostname`'
Вы оцениваете hostname
(там, конечно, может быть что-то вроде rm -rf /
)!
Очень-очень простая попытка защитить его, просто замените символы типа backtrick `и $:
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo" `hostname`'
declare -a "array=( $(echo $string | tr '`$<>' '????') )"
for item in "${array[@]}"; do echo "[$item]"; done
Теперь вы получили вывод, как:
[aString that may haveSpaces IN IT]
[bar]
[foo]
[bamboo]
[bam boo]
[?hostname?]
Более подробную информацию о методах, плюсах и минусах вы найдете в этом удачном ответе: https://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i- потребительная вместо /17529221 # 17529221
Но там все же оставлен вектор для атаки.
Я очень хочу иметь в bash метод строковых кавычек, как в двойных кавычках ("), но без интерпретации содержимого.