Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a list in Bash?

I have searched for a similar question here, but surprisingly could not find any.

In GNU bash, there is (a construct? a structure? a data type?) called "arrays". Arrays are well documented in the bash documentation, so I think that I understand the basics.

But suddenly, in the documentation there also comes up the term "list". For example, it is used when talking about filename expansion (emphasis is mine):

If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching).

Therefore, I have three questions:

  1. What does "list" mean here?
  2. Is it used in the same meaning as in for loop description?
  3. I am somehow lost in a whitespace world in bash. If this "list" is a separate concept to arrays (as I think), is it treated specially when it comes to whitespaces and IFS, or in the same way as an array?

There is another use of the "list" term when talking about sequence of one or more pipelines, but I am aware that it most probably means a different kind of lists.


UPDATE

  1. Since I see that the way that this "list structure" works is very similar to how arrays work – what are the differences between them?

UPDATE 2

  1. What are the uses cases when "lists" are preferred over arrays? For example, let us compare. Let us create two files:

    $ touch file1.txt file2.txt

When it comes to lists, I can do the following:

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

And when it comes to arrays, I can do the following:

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

While these two results are exactly the same, are there any cases when arrays and lists return different results?


UPDATE 3

I might have confuse something, because in the above example it seems to be a list "wrapped" in an array. I do not know whether it makes a difference.

like image 938
Silv Avatar asked Oct 19 '18 23:10

Silv


People also ask

What is an array in bash?

Bash Array – An array is a collection of elements. Unlike in many other programming languages, in bash, an array is not a collection of similar elements. Since bash does not discriminate string from a number, an array can contain a mix of strings and numbers.

How do you check if a value is in a list bash?

We can use regular expressions in Bash using [[ STRING =~ REGEX ]]. This command returns the value 0 if the regular expression matches. Otherwise, it returns the value 1. As we need this behavior in the exist_in_list function, we can run the [[ ]] command without any explicit return command.

What is list and arrays in Bash?

What Is List And Arrays In Bash There is no data structure in array with name List. But List is generally refer to the "list of items" in Bash Loops. Let us look at an example.

What is Bash in Linux?

Bash is a command processor that typically runs in a text window where the user types commands that cause actions. Bash can also read and execute commands from a file, called a shell script. Like all Unix shells, it supports filename globbing (wildcard matching), piping, here documents, command substitution, variables, ...

What are BASH characters and how do they work?

There are a set of characters the Bash shell treats in two different ways. When you type them at the shell, they act as instructions or commands and tell the shell to perform a certain function. Think of them as single-character commands. Sometimes, you just want to print a character and don’t need it to act as a magic symbol.

How to check if a bash array contains a value?

How to check if a Bash Array contains a value? There is no in array operator in bash to check if an array contains a value. Instead, to check if a bash array contains a value you will need to test the values in the array by using a bash conditional expression with the binary operator =~.


2 Answers

There is no data type called list in Bash. We just have arrays. In the documentation that you have quoted, the term "list" doesn't refer to a data type (or anything technical) - it just means a sequence of file names.

However, glob expansions work very similar to array elements as far as sequential looping is considered:

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

is same as

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

However, if you were to hardcode the file names, then you need quotes to prevent word splitting and globbing:

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

or

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

Read more about word splitting here:

  • Word Splitting - Greg's Wiki
  • Word Splitting - Bash Manual
  • Word splitting in Bash with IFS set to a non-whitespace character
  • I just assigned a variable, but echo $variable shows something else
like image 107
codeforester Avatar answered Oct 25 '22 13:10

codeforester


The term "list" is not really a specific technical term in bash; it is used in the grammar to refer to a sequence of commands (such as the body of a for loop, or the contents of a script), and this use has shown up in the documentation of program structure, but that's a very specific type of list.

In the context you ask about, I'd say a "list" is a value that consists of any number (including 0) of shell words. The arguments to a single command are such a list.

A shell word, in turn, is what you might call a single string in another language. Normally, when you type a command line, it is separated into words by the characters listed in $IFS (normally whitespace, that is, spaces and horizontal tabs), but you can avoid that by any of the various quoting mechanisms and thus create shell words that contain IFS characters.

If you wish to store a list in a shell parameter, that parameter must be an array; in that case, each word of the list becomes an element of the array. For example, the list of arguments passed into a command are available in the default array, which is accessed via $ followed by the index that would go in between the square brackets in a named array reference, e.g. "$@" for all the elements turned back into a list, "$0" for the first element (which is the command name), etc.

When an array is expanded back into a list of words, you have three options; the elements of the array can be kept as they originally were, irrespective of contents ("$@"); they can be concatenated together, joined by spaces, into one big single shell word ("$*"), or they can be first concatenated into one big string and then re-parsed into words using the usual IFS-delimiter rules ($@ or $* without the quotation marks).

Except for a few builtins like mapfile (a.k.a. readarray), bash doesn't have much support for arrays. For example, the environment can only contain strings, so you can't export an array. You can't pass an array into a function as an array, although you can certainly use the value of an array (or a slice of an array) as (some or all of) the list of arguments passed to a function. You can also pass the name of an array to a function, which can then use name-references and eval to manipulate that array in its caller's scope, but as with all mechanisms for reaching out of one's lexical scope in any language, this is generally considered bad practice. And of course, a function can't return an array, but then a bash function can't return anything but a one-byte numeric exit code. It can output text, but that text is unstructured; if the caller captures it with command or process substitution, it's up to that caller to parse the text however it desires – such as making an array containing one element word for each line of output, which is the default behavior of mapfile/readarray.

Anyway, the point is, lists in this context are values, while arrays are containers that store list values. Technically, shell parameters (a.k.a. "variables") can be arrays, and as arrays they can hold lists; they can't be lists, and it doesn't really make sense to refer to an "array value". But informally, "array" and "list" are often used interchangeably; that's the nature of lazy humans and the shell's fluidity.

like image 38
Mark Reed Avatar answered Oct 25 '22 14:10

Mark Reed