Цикл по массиву, предотвращающий расширение подстановочных знаков (*)

Я пытаюсь понять, что, как мне казалось, будет тривиальной проблемой в BASH, но мне трудно найти правильный синтаксис. Я хочу перебрать массив значений, одним из которых является звездочка (*), я не хочу, чтобы во время процесса происходило какое-либо расширение подстановочных знаков.

 WHITELIST_DOMAINS="* *.foo.com *.bar.com"
 for domain in $WHITELIST_DOMAINS
 do
    echo "$domain"
 done

У меня есть вышеизложенное, и я пытаюсь получить следующий результат:

 *
 *.foo.com
 *.bar.com

Вместо приведенного выше я получаю список каталогов в текущем каталоге, за которым следуют *.foo.com и *.bar.com

Я знаю, что мне нужно куда-то сбежать или процитировать... ранний утренний туман все еще сгущается в моем мозгу.

Я рассмотрел эти вопросы:

Как избежать расширения подстановочных знаков в переменной в bash?< /а>

Остановить расширение подстановочных знаков оболочки?


person Tal    schedule 06.11.2012    source источник


Ответы (2)


Ваша проблема в том, что вам нужен массив, но вы написали одну строку, содержащую элементы с пробелами между ними. Вместо этого используйте массив.

WHITELIST_DOMAINS=('*' '*.foo.com' '*.bar.com')

Всегда используйте двойные кавычки вокруг подстановок переменных (например, "$foo"), в противном случае оболочка разбивает значение переменной на отдельные слова и обрабатывает каждое слово как шаблон имени файла с подстановочными знаками. То же самое касается подстановки команд: "$(somecommand)". Для переменной массива используйте "${array[@]}", чтобы раскрыть список элементов массива.

for domain in "${WHITELIST_DOMAINS[@]}"
 do
    echo "$domain"
 done

Для получения дополнительной информации см. часто задаваемые вопросы по bash о массивах.

person Gilles 'SO- stop being evil'    schedule 06.11.2012
comment
Ладонь твердо прижата к лицу — я должен был знать, что не использую массив, спасибо, что указали на это так ясно — и быстро. - person Tal; 06.11.2012
comment
@иначе оболочка разбивает значение переменной на отдельные слова и обрабатывает каждое слово как шаблон подстановочного знака имени файла. Этот аспект сценариев оболочки может быть труднее всего запомнить при переходе между несколькими языками. Спасибо, что освежили мою память. - person Tal; 06.11.2012

Вы можете использовать массив для их хранения:

array=('*' '*.foo.com' '*.bar.com')

for i in "${array[@]}"
do
    echo "$i"
done
person kev    schedule 06.11.2012
comment
Это то же решение, что и принятый ответ, за исключением того, что @Giles дал немного более полезное объяснение для будущих пользователей, прогуливающихся через Google. Я принял его комментарий вместо вашего для полноты и потомства. - person Tal; 06.11.2012