Что такое список в Bash? - PullRequest
       1

Что такое список в Bash?

0 голосов
/ 20 октября 2018

Я искал подобный вопрос здесь, но неожиданно не смог найти ни одного.

В GNU bash есть (конструкция? Структура? Тип данных?), Называемая " массивы ».Массивы хорошо документированы в документации bash, поэтому я думаю, что понимаю основы.

Но неожиданно в документации также появляется термин «список».Например, он используется, когда речь идет о расширении имени файла (выделено мной):

Если появляется один из этих символов, то слово рассматривается как шаблон и заменяетсяс отсортированным по алфавиту списком имен файлов, соответствующих шаблону (см. Pattern Matching).

Поэтому у меня есть три вопроса:

  1. Что означает здесь «список»?
  2. Используется ли оно в том же значении, что и в для описания цикла ?
  3. Я каким-то образом потерян в мире пробеловв баш.Если этот «список» является отдельным понятием для массивов (как я думаю), он обрабатывается специально, когда речь идет о пробелах и IFS, или так же, как массив?

Там - еще одно использование термина "list" , когда речь идет о последовательности одного или нескольких конвейеров, но я знаю, что это, скорее всего, означает другой тип списков.


UPDATE

Поскольку я вижу, что способ, которым работает эта "структура списка", очень похож на работу массивов - чем они отличаются?

ОБНОВЛЕНИЕ 2

В каких случаях используются «списки», а не массивы?Например, давайте сравним.Давайте создадим два файла:

$ touch file1.txt file2.txt

Когда дело касается списков, я могу сделать следующее:

$ A=*.txt ; echo $A
file1.txt file2.txt
$ 

И когда дело доходит до массивов, я могу сделать следующее:

$ B=(*.txt) ; echo ${B[@]}
file1.txt file2.txt
$ 

Хотя эти два результата абсолютно одинаковы, есть ли случаи, когда массивы и списки возвращают разные результаты?


ОБНОВЛЕНИЕ 3

Возможно, я что-то запутал, потому что в приведенном выше примере это, кажется, список, «обернутый» в массив.Я не знаю, имеет ли это значение.

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Термин «список» не совсем конкретный технический термин в bash;он используется в грамматике для ссылки на последовательность команд (например, тело цикла for или содержимое скрипта), и это использование показано в документации о структуре программы, но это оченьконкретный тип списка.

В контексте, о котором вы спрашиваете, я бы сказал, что «список» - это значение , которое состоит из любого числа (включая 0) слов * оболочки.Аргументы для одной команды - это такой список.

Слово оболочки, в свою очередь, это то, что вы можете назвать одной строкой на другом языке.Обычно, когда вы набираете командную строку, она разделяется на слова символами, перечисленными в $IFS (обычно пробелами, то есть пробелами и горизонтальными табуляциями), но вы можете избежать этого с помощью любого из различных механизмов цитирования и, таким образом, создатьслова оболочки, содержащие символы IFS.

Если вы хотите сохранить список в параметре оболочки, этот параметр должен быть array ;в этом случае каждое слово списка становится элементом массива.Например, список аргументов, передаваемых в команду, доступен в массиве по умолчанию, доступ к которому осуществляется через $, за которым следует индекс, который будет заключен в квадратные скобки в именованной ссылке на массив, например, "$@" для всехэлементы превращаются обратно в список, "$0" для первого элемента (который является именем команды) и т. д.

Когда массив возвращается обратно в список слов, у вас есть три варианта;элементы массива могут быть сохранены такими, какими они были изначально, независимо от содержимого ("$@");они могут быть объединены вместе, соединены пробелами в одно большое слово оболочки ("$*"), или их можно сначала объединить в одну большую строку, а затем повторно проанализировать в слова, используя обычные правила пробела ($@)или $* без кавычек).

За исключением нескольких встроенных функций, таких как mapfile (он же readarray), bash не имеет большой поддержки массивов.Например, среда может содержать только строки, поэтому вы не можете export массив.Вы не можете передать массив в функцию как массив, хотя вы, конечно, можете использовать значение массива (или часть массива) как (некоторые или все) список переданных аргументовк функции.Вы также можете передать name массива в функцию, которая затем может использовать ссылки на имена и eval для манипулирования этим массивом в области его вызова;хотя это обычно считается плохой практикой.И, конечно, функция не может вернуть массив, но тогда функция bash не может вернуть ничего, кроме однобайтового числового кода выхода.Он может выводить текст, но этот текст неструктурирован;если вызывающий объект захватывает его с помощью подстановки команды или процесса, он может проанализировать текст по своему усмотрению - например, создать массив, содержащий одно слово элемента для каждой строки вывода, что является поведением по умолчанию mapfile / readarray.

В любом случае, суть в том, что списки - это значения, а массивы - это контейнеры, в которых хранятся значения списков.Технически, параметры оболочки (иначе говоря, «переменные») могут быть массивами, а в качестве массивов они могут содержать списки;они не могут быть списками, и на самом деле не имеет смысла ссылаться на «значение массива».Но неофициально, «массив» и «список» часто используются взаимозаменяемо;такова природа ленивых людей и текучесть скорлупы.

0 голосов
/ 20 октября 2018

Список в bash - это определенная последовательность выражений, разделенных конвейером.Начиная с man bash, например

Lists

   A list is a sequence of one or more pipelines separated by one of the 
   operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or 
   <newline>. 

   Of these list operators, && and || have equal precedence, followed by 
   ; and &, which have equal precedence.

   A sequence of one or more newlines may appear in a list instead of a 
   semicolon to delimit commands.

   If a command is terminated by the control operator &, the shell 
   executes the command in the background in a subshell. The shell does 
   not wait for the command to finish, and the return status is 0. 
   Commands separated by a ; are executed sequentially; the shell waits 
   for each command to terminate in turn. The return status is the exit 
   status of the last command executed.

   AND and OR lists are sequences of one of more pipelines separated by 
   the && and || control operators, respectively. AND and OR lists are 
   executed with left associativity. An AND list has the form

          command1 && command2

   command2 is executed if, and only if, command1 returns an exit status 
   of zero.

   An OR list has the form

          command1 || command2

   command2 is executed if and only if command1 returns a non-zero exit 
   status. The return status of AND and OR lists is the exit status of 
   the last command executed in the list.

A List используется при формировании Compound Commands (см. man bash).

Существует еще одно использование термина "список", когда речь идет о последовательности одного или нескольких конвейеров, но я знаю, что это, скорее всего, означает другой тип списков.

Оба:

$ A=*.txt ; echo $A

и

$ B=(*.txt) ; echo ${B[@]}

технически Lists в баш.

0 голосов
/ 20 октября 2018

В Bash нет типа данных с именем list .У нас просто есть массивы.В цитируемой вами документации термин «список» не относится к типу данных (или к чему-либо техническому) - он просто означает последовательность имен файлов.

Однако расширение glob работает очень похоже на элементы массива в том, что касается последовательного цикла:

for file in *.txt; do          # loop through the matching files
                               # no need to worry about white spaces or glob characters in file names
  echo "file=$file"
done

совпадает с

files=(*.txt)                  # put the list of matching files in an array
for file in "${files[@]}"; do  # loop through the array
  echo "file=$file"
done

Однако, если вам нужно жестко закодировать имена файлов, тогда вам нужноцитаты для предотвращения разбиения слов и глобализации:

for file in verycramped.txt "quite spacious.txt" "too much space.txt" "*ry nights.txt"; do ...

или

files=(verycramped.txt "quite spacious.txt" "too much space.txt" "*ry nights.txt")
for file in "${files[@]}"; do ...

Подробнее о разбиении слов здесь:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...