Почему echo {1,2,3}расширен до 1 2 3, что является ожидаемым поведением, а echo [[:digit:]]возвращается, [[:digit:]]пока я ожидал, что он будет печатать все цифры от 0до 9?
Потому что это две разные вещи. Это {1,2,3}пример расширения скобки . {1,2,3}Конструкция расширяется оболочкой , до того echoдаже не видит. Вы можете увидеть, что произойдет, если вы используете set -x:
$ set-x
$ echo {1,2,3}+ echo 123123
Как видите, команда echo {1,2,3}расширена до:
echo 123
Тем не менее, [[:digit:]]это класс символов POSIX . Когда вы передаете его echo, оболочка также сначала обрабатывает его, но на этот раз он обрабатывается как глобус оболочки . это работает так же, как если бы вы запустили, echo *который напечатает все файлы в текущем каталоге. Но [[:digit:]]это оболочка Глобо , которая будет соответствовать любой цифре. Теперь в bash, если глобус оболочки ничего не соответствует, он будет расширен до самого себя:
Если шарик совпадает с чем-то, это будет напечатано:
$ echo /e*c
+ echo /etc
/etc
В обоих случаях echoпросто печатает все, что говорит оболочка, чтобы распечатать, но во втором случае, так как глобус совпадает с чем-то ( /etc), ему говорят, что это нужно напечатать.
Итак, поскольку у вас нет файлов или каталогов, чье имя состоит ровно из одной цифры (что [[:digit:]]соответствует), глобус расширяется до самого себя, и вы получаете:
$ echo [[:digit:]][[:digit:]]
Теперь попробуйте создать файл с именем 5и запустить ту же команду:
$ echo [[:digit:]]5
И если есть несколько подходящих файлов:
$ touch 15
$ echo [[:digit:]]15
Это (вроде) задокументировано в man bashобъяснении nullglobопций, которые отключают это поведение:
nullglob
Ifset, bash allows patterns which match no files (see
PathnameExpansion above) to expand to a null string,
rather than themselves.
Смотрите также, shopt -s failglobчтобы получить более полезное поведение, подобное поведению современных оболочек типа zshor fish.
Стефан Шазелас
Я согласен со Стефаном, используйте failglob. nullglobможет вызвать непредвиденные проблемы, например, при вставке URL, который имеет ?.
Кевин
1
Конечно, я только упомянул, nullglobчтобы продемонстрировать, что паттерн интерпретируется оболочкой как глобус.
Terdon
14
{1,2,3}это расширение скобки , оно распространяется на слова, перечисленные без учета их значения.
[...]является группой символов, используемой в расширении имени файла (или подстановочный знак, или глобус) аналогично звездочке *и вопросительному знаку ?. Он соответствует любому отдельному символу в списке или символам, которые являются членами именованных групп, например, [:digit:]если они есть в списке. Поведение большинства оболочек по умолчанию - оставить подстановочный знак как есть, если нет файлов, соответствующих ему.
(Обратите внимание, что вы действительно не можете превратить подстановочный знак / шаблон в набор строк, которому он будет соответствовать. Звездочка может соответствовать любой строке любой длины, поэтому расширение любого шаблона, содержащего ее, приведет к бесконечному списку строк.)
Так:
$ bash -c 'echo [[:digit:]]'# bash leaves it as-is[[:digit:]]
$ zsh -c 'echo [[:digit:]]'# zsh by default complains if no match
zsh:1: no matches found:[[:digit:]]
$ touch 13 d i g t
$ bash -c 'echo [[:digit:]]'# now there are two matches13# note that d, i, g and t do NOT match
Но до сих пор:
$ bash -c 'echo {1,2,3}'123
Оба они расширяются оболочкой , не имеет значения, является ли команда, которую вы запускаете ls, или, echoили rm. Также обратите внимание, что если один из них указан в кавычках, они не будут расширены:
$ bash -c 'echo "[[:digit:]]"'# even though matching files still exist[[:digit:]]
$ bash -c 'echo "{1,2,3}"'{1,2,3}
спасибо за ваш ответ, я новичок в Linux, поэтому позвольте мне спросить вас, как эхо связано с файлами 1 3, его функция - выводить свои аргументы в стандартный вывод, не ища файлы, насколько мне известно
AbdAllah Talaat
1
@AbdAllahTalaat, на самом деле это не имеет ничего общего с эхом. Оболочка (например, bash) будет «расширять» [[:digit:]]перед передачей ее echo, поэтому echoникогда не видит [[:digit:]], она видит только 1 3. Вы можете увидеть это в действии, запустив, set -xкоторый напечатает фактические команды, которые выполняются (запустите, set +xчтобы выключить его снова).
Terdon
@AbdAllahTalaat, echoне ищет файлы, это делает оболочка перед запуском echo.
ilkkachu
Тем более, что я думаю, что в DOS / Windows утилиты расширяют подстановочные знаки, а не оболочку. (Возможно я ошибаюсь)
ilkkachu
извините, ребята, я переместил правильный ответ на ответ Тедрона, потому что его комментарий содержал значение, что bash - это то, что не отражается в работе ... его ответ тоже содержал это значение ... вы все помогли мне ... я хотел бы, если бы я мог поставить правильный ответ на все ваши ответы и комментарии
Абдаллах Талаат
4
{1,2,3}(и, например, {1..3}это фигурные расширения . Они интерпретируются оболочкой перед выполнением команды.
[[:digit:]]это токен, соответствующий шаблону , но вы не используете его в расположении с файлами, соответствующими этому шаблону. Если вы используете сопоставление с шаблоном, у которого нет совпадений, оно расширяется до самого себя:
Ответы:
Потому что это две разные вещи. Это
{1,2,3}
пример расширения скобки .{1,2,3}
Конструкция расширяется оболочкой , до тогоecho
даже не видит. Вы можете увидеть, что произойдет, если вы используетеset -x
:Как видите, команда
echo {1,2,3}
расширена до:Тем не менее,
[[:digit:]]
это класс символов POSIX . Когда вы передаете егоecho
, оболочка также сначала обрабатывает его, но на этот раз он обрабатывается как глобус оболочки . это работает так же, как если бы вы запустили,echo *
который напечатает все файлы в текущем каталоге. Но[[:digit:]]
это оболочка Глобо , которая будет соответствовать любой цифре. Теперь в bash, если глобус оболочки ничего не соответствует, он будет расширен до самого себя:Если шарик совпадает с чем-то, это будет напечатано:
В обоих случаях
echo
просто печатает все, что говорит оболочка, чтобы распечатать, но во втором случае, так как глобус совпадает с чем-то (/etc
), ему говорят, что это нужно напечатать.Итак, поскольку у вас нет файлов или каталогов, чье имя состоит ровно из одной цифры (что
[[:digit:]]
соответствует), глобус расширяется до самого себя, и вы получаете:Теперь попробуйте создать файл с именем
5
и запустить ту же команду:И если есть несколько подходящих файлов:
Это (вроде) задокументировано в
man bash
объясненииnullglob
опций, которые отключают это поведение:Если вы установите эту опцию:
источник
shopt -s failglob
чтобы получить более полезное поведение, подобное поведению современных оболочек типаzsh
orfish
.failglob
.nullglob
может вызвать непредвиденные проблемы, например, при вставке URL, который имеет?
.nullglob
чтобы продемонстрировать, что паттерн интерпретируется оболочкой как глобус.{1,2,3}
это расширение скобки , оно распространяется на слова, перечисленные без учета их значения.[...]
является группой символов, используемой в расширении имени файла (или подстановочный знак, или глобус) аналогично звездочке*
и вопросительному знаку?
. Он соответствует любому отдельному символу в списке или символам, которые являются членами именованных групп, например,[:digit:]
если они есть в списке. Поведение большинства оболочек по умолчанию - оставить подстановочный знак как есть, если нет файлов, соответствующих ему.(Обратите внимание, что вы действительно не можете превратить подстановочный знак / шаблон в набор строк, которому он будет соответствовать. Звездочка может соответствовать любой строке любой длины, поэтому расширение любого шаблона, содержащего ее, приведет к бесконечному списку строк.)
Так:
Но до сих пор:
Оба они расширяются оболочкой , не имеет значения, является ли команда, которую вы запускаете
ls
, или,echo
илиrm
. Также обратите внимание, что если один из них указан в кавычках, они не будут расширены:источник
[[:digit:]]
перед передачей ееecho
, поэтомуecho
никогда не видит[[:digit:]]
, она видит только1 3
. Вы можете увидеть это в действии, запустив,set -x
который напечатает фактические команды, которые выполняются (запустите,set +x
чтобы выключить его снова).echo
не ищет файлы, это делает оболочка перед запускомecho
.{1,2,3}
(и, например,{1..3}
это фигурные расширения . Они интерпретируются оболочкой перед выполнением команды.[[:digit:]]
это токен, соответствующий шаблону , но вы не используете его в расположении с файлами, соответствующими этому шаблону. Если вы используете сопоставление с шаблоном, у которого нет совпадений, оно расширяется до самого себя:источник