Розширення змінної оболонки та ефект глобула та розщеплення на нього


18

Цей пост насправді містить два окремі питання, але я думаю, що об'єднання їх разом дасть ще трохи контексту. Я пережив це питання щодо цитат навколо змінних, але я не зовсім розумію, що означає розширення змінної в першу чергу. Отже, моє перше питання:

  1. Що таке розширення розширення в розмові unix / linux?

Друга частина мого питання стосується наступних термінів:

  1. глобус
  2. розколоти

Що означають вищезазначені та як вони впливають на розширення змінної? У відповіді на початкове запитання згадується наступне:

Подумайте про відсутність лапок (у контекстах списку) як оператора split + glob.

Ніби echo $ test був echo glob (спліт ("$ test")).

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


Відповіді:


15

Змінне розширення (стандартний термін - це розширення параметрів , його також іноді називають заміною змінної ) в основному означає заміну змінної на її значення. Точніше, це означає заміну $VARIABLEконструкції (або ${VARIABLE}або ${VARIABLE#TEXT}інших конструкцій) іншим текстом, який будується зі значення змінної. Цей інший текст - це розширення змінної.

Процес розширення йде наступним чином. (Я обговорюю лише звичайний випадок, деякі параметри оболонки та розширення змінюють поведінку.)

  1. Візьміть значення змінної, яка є рядком. Якщо змінна не визначена, використовуйте порожній рядок.
  2. Якщо конструкція включає перетворення, застосуйте її. Наприклад, якщо конструкція є ${VARIABLE#TEXT}, а значення змінної починається з TEXT, видаліть TEXTз початку значення.
  3. Якщо контекст вимагає одного слова (наприклад, у подвійних лапках або в правій частині завдання або всередині документа тут), зупиніться тут. В іншому випадку продовжуйте наступні кроки.
  4. Розділіть значення на окремі слова в кожній послідовності пробілів. (Змінна IFSможе бути змінена на розділення на символи, відмінні від пробілів.) Таким чином, результат є вже не рядком, а списком рядків. Цей список може бути порожнім, якщо значення містило лише пробіл.
  5. Розгляньте кожен елемент списку як шаблон підстановки імені файлу, тобто глобул . Якщо шаблон відповідає деяким файлам, він замінюється списком відповідних імен файлів, інакше він залишається в спокої.

Наприклад, припустимо, що змінна fooмістить a* b* c*і поточний каталог містить файли bar, bazі paz. Потім ${foo#??}розгортається наступним чином:

  1. Значення змінної - це 8-символьна рядок a* b* c*.
  2. #??означає зняття перших двох символів, у результаті чого 6-символьний рядок  b* c*(з початковим пробілом).
  3. Якщо розширення знаходиться в контексті списку (тобто не в подвійних лапках чи іншому подібному контексті), продовжуйте.
  4. Розбийте рядок на розділені пробілами слова, в результаті чого вийде список з двох рядків: b*і c*.
  5. Рядок b*, інтерпретований як шаблон, відповідає двом файлам: barі baz. Рядок c*не відповідає жодному файлу, тому він залишається один. Результатом є список з трьох рядків: bar, baz, c*.

Наприклад, echo ${foo#??}друкує bar baz c*(команда echoз'єднує свої аргументи з пробілом між ними).

Докладніше див:


2
Зверніть увагу , що це називається розширенням параметра , оскільки це відноситься до змінних ( $var) і іншим типам параметрів , такі як $1, $#, $?, $-...
Stéphane Chazelas

12

глобус / спліт

Я спершу візьму глобус / спліт. @ Відповідь Стефана, з якою ви пов’язані, використовує ці терміни в загальному розумінні. Вони не є фактичними командами чи чимось подібним, просто псевдо-операціями.

Це split("$test")розділить вміст "$ test" на "масив" елементів.

glob(...)Буде потім дбати , щоб розширити будь-якого з цих елементів , які містять оболонки підстановки символи , такі як *або діапазонів [1-2].

Приклад

Скажімо, наш рядок $testтакий.

$ test="afile[1-2] afile[3-5]"

Скажімо, у нас є каталог з деякими файлами в ньому.

$ ls -1
afile1
afile2
afile3
afile4
afile5

Тепер, якщо ми спробуємо повторити його без лапок, ви повинні помітити, що наша струна розбилася на пробіли, а потім будь-які символи, що поширюються, розширилися.

$ echo $test
afile1 afile2 afile3 afile4 afile5

Однак якби ми цитували цю змінну, коли ми передавали її як аргумент, echoми отримаємо початковий буквальний рядок.

$ echo "$test"
afile[1-2] afile[3-5]

змінне розширення

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

У нашому попередньому прикладі. Коли змінна $testбула представлена ​​без echoкотирувань, ми говорили оболонці йти вперед і розділити ці аргументи, а потім поглибити їх.

Коли його котирували, ми фактично відключали цю особливість із будь-якою змінною (ими), яку ми обговорювали подвійними лапки.

Приклад

Ось кілька додаткових прикладів глобалізації та розщеплення.

глобул / розщеплення відбувається автоматично

$ echo file{1..3}
file1 file2 file3

$ echo file{1..3} dir{a..b}
file1 file2 file3 dira dirb

$ echo dir{z..w} file{A..D}
dirz diry dirx dirw fileA fileB fileC fileD

$ echo dir{z..w} file{A..B} fileC
dirz diry dirx dirw fileA fileB fileC

глобул / розділення відключено за допомогою подвійного цитування

$ echo "dir{z..w} file{A..B} fileC"
dir{z..w} file{A..B} fileC

$ echo "dir{z..w} file{A..B}"
dir{z..w} file{A..B}

Я не знав, що діапазони також працювали у зворотному порядку.
Джо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.