|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
|
Bash, at last, provides one-dimensional indexed and associative array variables. They can be declared implicitly (contextually) or explicitly. To explicitly declare an array, use
declare -a name
Initialization of arrays in bash has format similar to Perl:
solaris=(serv01 serv02 serv07 ns1 ns2 )
Space between opening "(" and first element is optional. the same is true for the last element and ")".
Each element of the array is a separate word in the list enclosed in parentheses. Then you can refer to each as ${solaris[0]}, ${solaris[1]}, ${solaris[2]} ...:
echo solaris10 is installed on ${solaris[2]}
If you omit index and use command "echo $solaris" you will get the first element of array too.
Another example taken from Bash Shell Programming in Linuxarray=(red green blue yellow magenta)
size=${#array[*]}
echo "The array has $size members. They are:"
i=0
while (( i < $size )); do
echo "$i: ${array[$i]}"
let i++
done
Run this example:
$ ./myscript.shThe array has 5 members. They are:
0: red 1: green 2: blue 3: yellow 4: magenta
The (( ...)) construct is also used in bash for a new, classic C-style form of for loop syntax, one that looks a lot like C Language:
for (( i=1; i<=n; i++ )) do touch file$i done for (( ; ; )) do echo "infinite loop [ hit CTRL+C to stop]" done
Its more general form this new, C-style loop can be described as:
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
The use of double parentheses indicates that expressions can use syntax of ((..)) construct.
Several iteration counters can be used. For example:
for (( i=0, j=0 ; i < 10 ; i++, j++ )) do echo $((i*j)) done
That for loop initializes two variables (i and j), then increments them both. The comma operator is used in the first and the third expressions.
Here is example of usage of arrays in Relax-and-Recover backup software, written completely in Bash ( 40_create_include_exclude_files.sh )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# backup all local filesystems, as defined in mountpoint_device
for k in "${BACKUP_PROG_INCLUDE[@]}" ; do
test "$k" && echo "$k"
done > $TMP_DIR/backup-include.txt
# add the mountpoints that will be recovered to the backup include list
while read mountpoint device junk ; do
if ! IsInArray "$mountpoint" "${EXCLUDE_MOUNTPOINTS[@]}" ; then
echo "$mountpoint"
fi
done <"$VAR_DIR/recovery/mountpoint_device" >> $TMP_DIR/backup-include.txt
# exclude list
for k in "${BACKUP_PROG_EXCLUDE[@]}" ; do
test "$k" && echo "$k"
done > $TMP_DIR/backup-exclude.txt
# add also the excluded mount points to the backup exclude list
for k in "${EXCLUDE_MOUNTPOINTS[@]}" ; do
test "$k" && echo "$k/"
done >> $TMP_DIR/backup-exclude.txt
|
Here are some additional examples from Advanced Bash scripting guide:
Example 10-12. A C-like for loopfor ((a=1; a <= LIMIT ; a++)) # Double parentheses, and "LIMIT" with no "$". do echo -n "$a " done # A construct borrowed from 'ksh93'. echo; echo # +=========================================================================+ # Let's use the C "comma operator" to increment two variables simultaneously. for ((a=1, b=1; a <= LIMIT ; a++, b++)) # The comma chains together operations. do echo -n "$a-$b" done echo; echo exit 0
Arrays are lists of values that are created with the -a (array) attribute. A number called an index refers to the position item in the array. Bash arrays differ from arrays in other computer languages because they are open-ended. Arrays can be any length and are initially filled with empty strings for items.
declare -a matrix
New items are assigned to the array using square brackets to indicate the position in the list. The first position is position zero (not one). If an initial value is specified, it is assigned to the first position. Assigning one value is not particularly useful but is included for compatibility with other shells. Alternatively, the initial values can be assigned to specific positions by including a position in square brackets.
declare -a blades [0]="b1" blades [1]="b2" blades [2]="b8"Arrays remain in existence until the script ends or until the variable is destroyed with the built-in unset command.
unset bladesThe action of this command can be understood if you remember that bash creates a table for each variable it find in the script. when it encounter unset command this line of the table is simple deleted. This is how bash "forget" the variables.
The unset command is a command so it needs to be executed to produce the desired effect.
Because of the square brackets, use curly braces to delineate the variable name and supersede the shell's pathname matching process.
echo "${ DATACENTER [0]}" accounting echo "${ DATACENTER [2]}" Morristown Raleigh
All unassigned positions in an array have no value. The position number 5 in the SERVERS array, for example, is initially an empty string. It can be assigned a value of Dell with an assignment statement.
printf "%s" "${SERVERS[5]}" SERVERS[5]="Dell" printf "%s" "${SERVERS[5]}" Dell
If there is an item in position zero, it is also the value returned when no position is specified.
SERVERS[0]="HP" printf "%s" "$SERVERS" HP printf "%s" "${SERVERS[0]}" HP
The entire array can be accessed using an asterisk (*) or an at sign (@) for the array position. These two symbols differ only when double quotes are used: The asterisk returns one string, with each item separated with the first character of the IFS variable (usually space), and the at sign returns each item as a separate string with no separation character.
printf "%s" "${SERVERS[*]}" printf "%s" "${SERVERS[@]}"
In this example, the at sign version requires two separate %s formatting codes to display the array properly, one for each array item.
printf "%s %s\n" "${SERVERS[@]}" HP Dell
Multiple values can be assigned with a list in parentheses.
BRANCHES=( "Asia" "North America" "Europe" ) printf "%s\n" "${BRANCHES[*]}" Asia North America Europe
The list items can have an optional subscript.
BRANCHES=( [1]="Asia" [2]="North America" [3]="Europe" ) printf "%s\n" "${BRANCHES[*]}" Asia Europe North America
Combining a list with a declare command, arrays can be assigned values at the time they are created.
The number of items in the array is returned when # is used in front of the variable name with a position of * or @. The items need not be assigned consecutively and the number doesn't reflect where the items are stored.
printf "%d" "${#BRANCHES[*]}" 3
Individual array values can be removed with the unset command. Erasing a value by assigning the array position an empty string doesn't destroy it: The empty string is still treated as an array item whenever the items are counted.
The read command can read a list into an array using an -a (array) switch. When this switch is used, each item on the line of input is read into a separate array position.
The array attribute is the only variable attribute that cannot be turned off after it is turned on. If Bash allowed the attribute to be turned off, the data in the array would be lost when the array became a normal variable.
Mitch Frazier in his article Bash Arrays published in Linux Journal (Jun 19, 2008) provides some additional information
If you're used to a "standard" *NIX shell you may not be familiar with bash's array feature. Although not as powerful as similar constructs in the P languages (Perl, Python, and PHP) and others, they are often quite useful.
Bash arrays have numbered indexes only, but they are sparse, ie you don't have to define all the indexes. An entire array can be assigned by enclosing the array items in parenthesis:
arr=(Hello World)Individual items can be assigned with the familiar array syntax (unless you're used to Basic or Fortran):arr[0]=Hello arr[1]=WorldBut it gets a bit ugly when you want to refer to an array item:echo ${arr[0]} ${arr[1]}To quote from the man page:The braces are required to avoid conflicts with pathname expansion.In addition the following funky constructs are available:
${arr[*]} # All of the items in the array ${!arr[*]} # All of the indexes in the array ${#arr[*]} # Number of items in the array ${#arr[0]} # Length if item zeroThe ${!arr[*]} is a relatively new addition to bash, it was not part of the original array implementation.The following example shows some simple array usage (note the "[index]=value" assignment [5]=five below to assign a specific index):
#!/bin/bash array=(one two three four [5]=five) echo "Array size: ${#array[*]}" echo "Array items:" for item in ${array[*]} do printf " %s\n" $item done echo "Array indexes:" for index in ${!array[*]} do printf " %d\n" $index done echo "Array items and indexes:" for index in ${!array[*]} do printf "%4d: %s\n" $index ${array[$index]} doneRunning it produces the following output:Array size: 5 Array items: one two three four five Array indexes: 0 1 2 3 5 Array items and indexes: 0: one 1: two 2: three 3: four 5: fiveNote that the "@" sign can be used instead of the "*" in constructs such as ${arr[*]}, the result is the same except when expanding the items of the array within a quoted string. In this case the behavior is the same as when expanding "$*" and "$@" within quoted strings: "${arr[*]}" returns all the items as a single word, whereas "${arr[@]}" returns each item separately: one item one word.
The following example shows how unquoted, quoted "*", and quoted "@" affect the expansion (particularly important when the array items themselves contain spaces):
#!/bin/bash array=("first item" "second item" "third" "item") echo "Number of items in original array: ${#array[*]}" for ix in ${!array[*]} do printf " %s\n" "${array[$ix]}" done echo arr=(${array[*]}) echo "After unquoted expansion: ${#arr[*]}" for ix in ${!arr[*]} do printf " %s\n" "${arr[$ix]}" done echo arr=("${array[*]}") echo "After * quoted expansion: ${#arr[*]}" for ix in ${!arr[*]} do printf " %s\n" "${arr[$ix]}" done echo arr=("${array[@]}") echo "After @ quoted expansion: ${#arr[*]}" for ix in ${!arr[*]} do printf " %s\n" "${arr[$ix]}" doneWhen run it outputs:Number of items in original array: 4 first item second item third item After unquoted expansion: 6 first item second item third item After * quoted expansion: 1 first item second item third item After @ quoted expansion: 4 first item second item third itemMitch Frazier is the System Administrator at Linux Journal.
If some elements of an indexed array are unset, the array is left with holes and it becomes a sparse array. It will then be impossible to traverse the array merely by incrementing an index. There are various ways of dealing with such an array. To demonstrate, let’s create an array and poke some holes in it:
array=( a b c d e f g h i j ) unset array[2] array[4] array[6] array[8]
The array now contains six elements instead of the original ten:
$ sa "${array[@]}" :a: :b: :d: :f: :h: :j:
One way to iterate through all the remaining elements is to expand them as arguments to for. In this method, there is no way of knowing what the subscript for each element is:
for i in "${array[@]}" do : do something with each element, $i, here done
With a packed array (one with no holes), the index can start at 0 and be incremented to get the next element. With a sparse (or any) array, the ${!array[@]} expansion lists the subscripts:
$ echo "${!array[@]}" 0 1 3 5 7 9
This expansion can be used as the argument to for:
for i in "${!array[@]}" do : do something with ${array[$i]} here done
That solution does not provide a method of referring to the next element. You can save the previous element yet not get the value of the next one. To do that, you could put the list of subscripts into an array and use its elements to reference the original array. It’s much simpler to pack the array, removing the holes:
$ array=( "${array[@]}" ) $ echo "${!array[@]}" 0 1 2 3 4 5
Note that this will convert an associative array to an indexed array.
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|
You can use PayPal to to buy a cup of coffee for authors of this site |
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: March, 12, 2019