From 6a42c8de66e3b2dc7293ddeadaa3ee396db2624d Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 12 Oct 2013 13:47:42 -0400 Subject: initial commit --- public/bash-arrays.md | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 public/bash-arrays.md (limited to 'public/bash-arrays.md') diff --git a/public/bash-arrays.md b/public/bash-arrays.md new file mode 100644 index 0000000..697d018 --- /dev/null +++ b/public/bash-arrays.md @@ -0,0 +1,201 @@ +Bash arrays +=========== +:copyright 2013 Luke Shumaker + +Way too many people don't understand Bash arrays. Many of them argue +that if you need arrays, you shouldn't be using Bash. If we reject +the notion that one should never use Bash for scripting, then thinking +you don't need Bash arrays is what I like to call "wrong". + +The simple expanation of why everybody who programs in Bash needs to +understand arrays is this: command line arguments are exposed as an +array. Does your script take any arguments on the command line? +Great, you need to work with an array! + +General array syntax +-------------------- + +The most important things to understanding arrays is to quote them, +and understanding the difference between `@` and `*`. + + + + + + + + + + + + +
+

Getting the entire array

+

There is no valid reason to not wrap these in double + quotes.

+
"${array[@]}"Returns every element of the array as a separate token.
"${array[*]}"Returns every element of the array in a single + whitepace-separated string.
+ +It's really that simple—that covers most usages of arrays, and most of +the mistakes made with them. + +To help you understand the difference between `@` and `*`, here is a +sample. + +
#!/bin/bash
+array=(foo bar baz)
+for item in "${array[@]}"; do
+        echo " - <${item}>"
+done
- <foo> + - <bar> + - <baz>
+ +
#!/bin/bash
+array=(foo bar baz)
+for item in "${array[@]}"; do
+        echo " - <${item}>"
+done
- <foo bar baz>
+ +To get individual entries, the syntax is +${array[n]}, where n starts at 0. + + + + + + + + + +
+

Getting a single entry from the array

+
"${array[n]}"Returns the nth entry of the array, where the + first entry is at n=0.
+ +To get a subset of the array, there are a few options (like normal, +switch between `@` and `*` to switch between +getting it as separate items, and as a whitespace-separated string): + + + + + + + + + + + + + + + +
+

Getting subsets of an array

+

Substitute * for @ to get the subset + as a whitespace-separated string instead of separate tokens, as + described above.

+

Again, there is no valid reason to not wrap each of these in + double quotes.

+
"${array[@]:start}"Returns from n=start to the end of the array.
"${array[@]:start:count}"Returns count entries, starting at n=start.
"${array[@]::count}"Returns count entries from the beginning of the array.
+ +Notice that `"${array[@]}"` is equivalent to `"${array[@]:0}"`. + + + + + + + + + +
+

Getting the length of an array

+

The is the only situation where there is no difference + between @ and *.

+
+ ${#array[@]} +
or
+ ${#array[*]} +
+ Returns the length of the array +
+ +Accessing the arguments array +----------------------------- + +Accessing the arguments is mostly that simple, but that array doesn't +actually have a variable name. It's special. Instead, it is exposed +through a series of special variables (normal variables can only start +with letters and underscore), that *mostly* match up with the normal +array syntax. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Accessing the arguments array

+ +
Individual entries
${array[0]}$0
${array[1]}$1
...
${array[9]}$9
${array[10]}${10}
...
${array[n]}${n}
Subset arrays (array)
"${array[@]}""${@:0}"
"${array[@]:1}""$@"
"${array[@]:pos}""${@:pos}"
"${array[@]:pos:len}""${@:pos:len}"
"${array[@]::len}""${@::len}"
Subset arrays (string)
"${array[*]}""${*:0}"
"${array[*]:1}""$*"
"${array[*]:pos}""${*:pos}"
"${array[*]:pos:len}""${*:pos:len}"
"${array[*]::len}""${*::len}"
Array length
${#array[@]}$# + 1
+ +Did notice what was inconsistent? The variables `$*`, `$@`, and `$#` +behave like the n=0 entry doesn't exist. + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Inconsistencies

+
@ or *
"${array[@]}""${array[@]:0}"
"${@}""${@:1}"
#
"${#array[@]}"length
"${#}"length-1
+ +These make sense because argument 0 is the name of the script—we +almost never want that when parsing arguments. You'd spend more code +getting the values that it currently gives you. -- cgit v1.2.3-54-g00ecf