Я пытаюсь раскрыть строку, включающую подстановочный знак и набор расширений, указанных в фигурных скобках. Ничто не работает, как показано в примере ниже. переменная firstList
расширяется штраф, но ни один secondList
, thirdList
или fourthList
расширяется должным образом. Я также пробовал разные версии, eval
но ни одна не работает. Любая помощь будет оценена
#!/bin/bash
touch a.ext1
touch b.ext1
firstList='*.ext1'
ls $firstList
touch a.ext2
touch b.ext2
secondList='*.{ext1,ext2}'
ls $secondList
ls '$secondList'
ls "$secondList"
thirdList=*.{ext1,ext2}
ls $thirdList
ls '$thirdList'
ls "$thirdList"
fourthList="*.{ext1,ext2}"
ls $fourthList
ls '$fourthList'
ls "$fourthList"
bash
brace-expansion
Лео Симон
источник
источник
eval ls $secondList
отлично работает здесь ... что вы пытаетесь достичь?eval
получить 2-й раунд расширений.Ответы:
Оболочка расширяется
*
только тогда , когда расширение не-цитируемым, любая ссылка останавливается оболочкой.Кроме того, расширение скобки должно быть без кавычек, чтобы быть расширенным оболочкой.
Эта работа (давайте посмотрим на echo, что делает оболочка):
Даже если есть файлы с некоторыми другими именами:
Почему это работает?
Важно, чтобы мы понимали, почему это работает. Это из-за порядка расширения. Сначала «Расширение скобок», а затем (последнее) «Расширение пути» (он же glob-расширение).
Мы можем отключить «Расширение пути» на мгновение:
«Расширение пути» получает два аргумента:
*.ext1
и*.ext2
.Проблема в том, что мы не можем использовать переменную для расширения скобки.
Это было объяснено много раз прежде для использования переменной внутри «расширения скобки»
Чтобы развернуть «Расширение скобок», являющееся результатом «Расширения переменных», необходимо повторно передать командную строку в оболочку с помощью
eval
.Значения имен файлов не вызывают проблем с выполнением для eval:
Но ценность
$list
может быть небезопасной. Однако значение$list
устанавливается автором сценария. Автор сценария контролируетeval
: Просто не используйте внешние значения для$list
. Попробуй это:Лучшая альтернатива.
Альтернативой (без eval) является использование Bash «Extended Patterns» :
Примечание. Обратите внимание, что оба решения (eval и pattern) (как написано) безопасны для имен файлов с пробелами или новыми строками. Но потерпит неудачу для
$list
с пробелами, потому$list
что без кавычек или Eval удаляет кавычки.источник
Рассматривать:
Проблема в том, что расширение скобки выполняется перед расширением переменной . Это означает, что, как указано выше, расширение скобок никогда не выполняется.
Это связано с тем, что когда bash впервые видит командную строку, фигурных скобок нет. После того,
secondList
как расширен, это слишком поздно.Следующее будет работать:
Здесь командная строка имеет фигурные скобки, так что расширение фигурных скобок может выполняться как первый шаг. После этого
$s
подставляется значение ( расширение переменной ) и, наконец , выполняется расширение имени пути .Документация
man bash
объясняет порядок расширения:источник