Що робить `. []. Foo []` в баші? Чому він відповідає `..`?


16

Подивіться на наступне:

$ echo .[].aliases[]
..
$ echo .[].foo[]
..
$ echo .[].[]
..
$ echo .[].xyz[]
..
$ echo .xyz[].xyz[]
.xyz[].xyz[]
$ echo .xyz[].[]
.xyz[].[]

Мабуть, це, здається, щось глобалізує, але я не розумію, як виходить результат. З мого розуміння []це порожній клас персонажів. Було б інтуїтивно, якби

  • вона відповідала лише порожній рядку; у цьому випадку я б очікував, що баш відтвориться в повному обсязі, оскільки в цьому каталозі нічого не відповідає, але також відповідає таким речам, як ..aliases(у першому прикладі),
  • або взагалі нічого; в цьому випадку я б очікував, що bash також відтворить рядок.

Це з BNU bash, версія 4.4.23 (1) -випуск.

Відповіді:


25

[Починається набір. Набір припиняється ]. Але є спосіб бути ]частиною набору, а це вказати ]як перший символ. Оскільки порожній набір не має сенсу, це неоднозначно.

Отже, ваші приклади - це загалом усі точки, за якими слідує набір, який містить крапку, тому він відповідає двом крапкам.

Пізніші приклади не знаходять жодних файлів і тому повертаються дослівно.


4

Тільки рядки, що цитуються , не підлягають глобалізації:

$ echo ".[].aliases[]"
.[].aliases[]

Але рядки, які не котируються, підлягають глобалізації. Рядок без котирування, що містить a *або a ?(дійсний) [](дужка вираз), буде змінено списком файлів, які відповідають йому. Точно так само, як а *перетворюється на всі файли у відповідній папці, а файл ?буде відповідати файлам лише одного символу, а (дійсний) []буде відповідати файлам із символами всередині дужок. Крапка - дійсний символ:

$ echo a[.]b
a[.]b

$ touch "a.b"
$ echo a[.]b
a.b

Щоб мати можливість відповідати, ]він повинен бути першим символом у дужках:

$ touch "a]b"
$ ls a[]]b
a]b

Вираз порожнього дужки не має сенсу (і не розширюється):

$ touch ab
$ ls a[]b
ls: cannot access 'a[]b': No such file or directory

Ось чому це працює:

$ touch a]c abc afc azc a:c a?c aoc 
$ ls a[]bfz:?]c
abc  a:c  a?c  a]c  afc  azc

Для [ідеї аналогічна:

$ touch a[c
$ ls a[[]c
a[c

але це може бути в будь-якій позиції в дужковому виразі:

$ ls a[]bf[z:?]c
abc  a:c  a?c  a[c  a]c  afc  azc

$ ls a[]bfz:?[]c
abc  a:c  a?c  a[c  a]c  afc  azc

Рядок, який ви розмістили .[].foo[], відповідатиме крапці, за якою слідує або a ], a ., a f, a oчи a [. Це схоже на:

$ echo a[].foo[]c
a[c a]c afc aoc

І воно буде відповідати наступним чином:

$ touch .] .f .o .[ .a .b .z

$ echo .[].foo[]
.. .[ .] .f .o

Зауважте, що запис каталогів ..не потрібно створювати, оскільки він існує за кожним каталогом за замовчуванням. Але просту крапку .не порівнюватиме глобус, оскільки її потрібно явно зіставити (фактично використовуючи крапку).

Але це не збігатиметься, ..aliasesоскільки вираз дужки буде відповідати лише одному символу. Щоб відповідати декільком символам, потрібно використовувати *(що-небудь):

$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo .[].aliases[]
.. .[ .] .a

$ echo .[].aliases[]*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.