1. For Loop:
BASH中for loop有以下幾種寫法:
The for loop syntax is as follows:
for var in item1 item2 ... itemN
do
command1
command2
....
...
commandN
done
The for loop numerical explicit list syntax:
for var in list-of-values
do
command1
command2
....
...
commandN
done
The for loop explicit file list syntax:
for var in file1 file2 file3 fileN
do
command1
command2
....
...
commandN
done
The for loop variable's contents syntax:
for var in $fileNames
do
command1
command2
....
...
commandN
done
The for loop command substitution syntax:
for var in $(Linux-command-name)
do
command1
command2
....
...
commandN
done
The for loop explicit file list using bash array syntax:
# define an array
ArrayName=(~/.config/*.conf)
for var in "${ArrayName[@]}"
do
command1 on $var
command2
....
...
commandN
done
The for loop three-expression syntax ( this type of for loop share a common heritage with the C programming language ):
for (( EXP1; EXP2; EXP3 ))
do
command1
command2
command3
done
The for loop execute a command line once for every new value assigned to a var (variable) in specified list (item1...itemN) i.e. repeat all statement between do and done till condition is not satisfied. The lists or values are normally:
- Strings
- Numbers
- Command line arguments
- File names
- Linux command output
Example
Create a shell script called testforloop.sh:
#!/bin/bash for i in 1 2 3 4 5 do echo "Welcome $i times." done
Save and close the file. Run it as follows:
chmod +x testforloop.sh ./testforloop.sh
The for loop first creates i variable and assigned a number to i from the list of number from 1 to 5. The shell execute echo statement for each assignment of i. This is known as iteration. This process will continue until all the items in the list were not finished. See bash for loop examples page for more information.
The For Loop Using Strings
Create a shell script called forcars.sh
#!/bin/bash # A simple shell script to print list of cars for car in bmw ford toyota nissan do echo "Value of car is: $car" done
Another example, create a shell script called forcmds.sh:
#!/bin/bash # A simple shell script to run commands for command in date pwd df do echo echo "*** The output of $command command >" #run command $command echo done
Save and close the file. Run it as follows:
chmod +x forcmds.sh ./forcmds.sh
Sample outputs:
*** The output of date command > Sun Sep 6 14:32:41 IST 2009 *** The output of pwd command > /1.5/share/data/songs *** The output of df command > Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb2 96116904 27589760 63644592 31% / tmpfs 4149972 0 4149972 0% /lib/init/rw varrun 4149972 272 4149700 1% /var/run varlock 4149972 0 4149972 0% /var/lock udev 4149972 2808 4147164 1% /dev tmpfs 4149972 356 4149616 1% /dev/shm /dev/sdb5 286374908 274733944 11640964 96% /share /dev/sdc2 240402848 159452732 68738308 70% /disk1p2 /dev/sda5 1341352436 412128756 861086932 33% /1.5 /dev/sdd1 1442145212 26365188 1342523224 2% /media/backup
The For Loop Using Variable's Contents
Create a shell script called forfilenames.sh
#!/bin/bash # A shell script to verify user password database files="/etc/passwd /etc/group /etc/shadow /etc/gshdow" for f in $files do [ -f $f ] && echo "$f file found" || echo "*** Error - $f file missing." done
The For Loop Using Command-line Arguments
Create a shell script called forcmdargs.sh:
#!/bin/bash # A simple shell script to display a file on screen passed as command line argument [ $# -eq 0 ] && { echo "Usage: $0 file1 file2 fileN"; exit 1; } # read all command line arguments via the for loop for f in $* do echo echo "< $f >" [ -f $f ] && cat $f || echo "$f not file." echo "------------------------------------------------" done
Save and close the file. Run it as follows:
chmod +x forcmdargs.sh ./forcmdargs.sh /etc/resolv.conf /etc/hostname
Sample outputs:
< /etc/resolv.conf > nameserver 127.0.0.1 nameserver 4.2.2.1 nameserver 4.2.2.2 ------------------------------------------------ < /etc/hostname > vivek-desktop ------------------------------------------------
The for loop using command substitution
Command substitution is nothing but a shell command output stored in into a string or a variable. The command is a shell command and must be enclosed between grave accents or $(..). The syntax is as follows:
$(command-name) `command-name` var=$(command-name) NOW=$(date) echo $NOW
Create a shell script called forcmdsub.sh:
#!/bin/bash echo "Printing file names in /tmp directory:" for f in $(ls /tmp/*) do echo $f done
The for loop using ranges or counting
The for loop can be set using the numerical range. The range is specified by a beginning and ending number. The for loop executes a sequence of commands for each member in a list of items. A representative example in BASH is as follows to display multiplication table with for loop (multiplication.sh):
#!/bin/bash n=$1 # make sure command line arguments are passed to the script if [ $# -eq 0 ] then echo "A shell script to print multiplication table." echo "Usage : $0 number" exit 1 fi # Use for loop for i in {1..10} do echo "$n * $i = $(( $i * $n))" done
Save and close the file. Run it as follows:
chmod +x multiplication.sh ./multiplication.sh ./multiplication.sh 13
Sample outputs:
13 * 1 = 13 13 * 2 = 26 13 * 3 = 39 13 * 4 = 52 13 * 5 = 65 13 * 6 = 78 13 * 7 = 91 13 * 8 = 104 13 * 9 = 117 13 * 10 = 130
2. while loop
The while loop syntax
The syntax is:
while [ condition ] do command1 command2 .. .... commandN done
Command1..commandN will execute while a condition is true. To read a text file line-by-line, use the following syntax:
while IFS= read -r line do command1 on $line command2 on $line .. .... commandN done < "/path/to/filename"
OR
while IFS= read -r field1 filed2 field3 ... fieldN do command1 on $field1 command2 on $field1 and $field3 .. .... commandN on $field1 ... $fieldN done < "/path/to dir/file name with space"
IFS is used to set field separator (default is while space). The -r option to read command disables backslash escaping (e.g., \n, \t). This is failsafe while read loop for reading text files.
while loop Example
Create a shell script called while.sh:
#!/bin/bash # set n to 1 n=1 # continue until $n equals 5 while [ $n -le 5 ] do echo "Welcome $n times." n=$(( n+1 )) # increments $n done
Save and close the file. Run it as follows:
chmod +x while.sh ./while.sh
Sample outputs:
Welcome 1 times. Welcome 2 times. Welcome 3 times. Welcome 4 times. Welcome 5 times.
The script initializes the variable n to 1, and then increments it by one. The while loop prints out the "Welcome $n times" until it equals 5 and exit the loop.
Using ((expression)) Format With The While Loop
You can use ((expression)) syntax to test arithmetic evaluation (condition). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. To replace while loop condition while [ $n -le 5 ] with while (( num <= 10 )) to improve code readability:
#!/bin/bash n=1 while (( $n <= 5 )) do echo "Welcome $n times." n=$(( n+1 )) done
Reading A Text File
You can read a text file using read command and while loop as follows (whilereadfile.sh):
#!/bin/bash file=/etc/resolv.conf while IFS= read -r line do # echo line is stored in $line echo $line done < "$file"
Save and close the file. Run it as follows:
chmod +x whilereadfile.sh ./whilereadfile.sh
Sample outputs:
nameserver 127.0.0.1 nameserver 192.168.1.254 nameserver 4.2.2.1
Reading A Text File With Separate Fields
You can store above output in two separate fields as follows (whilereadfields.sh):
#!/bin/bash file=/etc/resolv.conf while IFS= read -r f1 f2 do echo "field # 1 : $f1 ==> field #2 : $f2" done < "$file"
Run it as follows:
chmod +x whilereadfields.sh ./whilereadfields.sh
Sample outputs:
field # 1 : nameserver ==> field #2 : 127.0.0.1 field # 1 : nameserver ==> field #2 : 192.168.1.254 field # 1 : nameserver ==> field #2 : 4.2.2.1
Another useful example for reading and phrasing /etc/passwd file using the while loop (readpasswd.sh):
#!/bin/bash file=/etc/passwd # set field delimiter to : # read all 7 fields into 7 vars while IFS=: read -r user enpass uid gid desc home shell do # only display if UID >= 500 [ $uid -ge 500 ] && echo "User $user ($uid) assigned \"$home\" home directory with $shell shell." done < "$file"
Save and close the file. Run it as follows:
chmod +x readpasswd.sh ./readpasswd.sh
3. until loop
Syntax
The until loop continues running commands as long as the item in list continues to evaluate true. Once an item evaluates false, the loop is exited. The syntax is:
until [ condition ] do command1 command2 ... .... commandN done
The while loop vs the until loop
- The until loop executes until a nonzero status is returned.
- The while command executes until a zero status is returned.
- The until loop always executes at least once.
Example
Create a shell script called until.sh:
#!/bin/bash i=1 until [ $i -gt 6 ] do echo "Welcome $i times." i=$(( i+1 )) done
Save and close the file. Run it as follows:
chmod +x until.sh ./until.sh
Sample outputs:
Welcome 1 times. Welcome 2 times. Welcome 3 times. Welcome 4 times. Welcome 5 times. Welcome 6 times.
The loop in the above example initializes the variable i to 1, and then increments and displays out the message until it equals 6.
4. select loop
The Bash Shell also offer select Loop, the syntax is:
select varName in list do command1 command2 .... ...... commandN done
OR (combine both select and case statement)
select varName in list do case $varName in pattern1) command1;; pattern2) command2;; pattern1) command3;; *) echo "Error select option 1..3";; esac done
- Select command use PS3 variable to print its prompt.
- Each word in list is printed on screen preceded by a number.
- If the line consists of the number corresponding to one of the displayed words (from the list), then varName is set to that word. You can use if..else.fi or case..in..esacto make a decision.
- If the line is empty, WORDS and the prompt are redisplayed.
- If EOF (end of file) is read, the command completes.
- The loop continues until a break (CTRL+C) is encountered.
Example
Create a shell script called select.sh:
#!/bin/bash # Set PS3 prompt PS3="Enter the space shuttle to get more information : " # set shuttle list select shuttle in columbia endeavour challenger discovery atlantis enterprise pathfinder do echo "$shuttle selected" done
Save and close the file. Run it as follows:
chmod +x select.sh ./select.sh
Sample outputs:
/tmp/x.sh 1) columbia 3) challenger 5) atlantis 7) pathfinder 2) endeavour 4) discovery 6) enterprise Enter the space shuttle name to get more information : 1 columbia selected Enter the space shuttle name to get more information :
Combining the select and the case statement
Another select loop example and decision making does with case..in..esac statement (selectshuttle.sh):
#!/bin/bash # The default value for PS3 is set to #?. # Change it i.e. Set PS3 prompt PS3="Enter the space shuttle to get quick information : " # set shuttle list select shuttle in columbia endeavour challenger discovery atlantis enterprise pathfinder do case $shuttle in columbia) echo "--------------" echo "Space Shuttle Columbia was the first spaceworthy space shuttle in NASA's orbital fleet." echo "--------------" ;; endeavour) echo "--------------" echo "Space Shuttle Endeavour is one of three currently operational orbiters in the Space Shuttle." echo "--------------" ;; challenger) echo "--------------" echo "Space Shuttle Challenger was NASA's second Space Shuttle orbiter to be put into service." echo "--------------" ;; discovery) echo "--------------" echo "Discovery became the third operational orbiter, and is now the oldest one in service." echo "--------------" ;; atlantis) echo "--------------" echo "Atlantis was the fourth operational shuttle built." echo "--------------" ;; enterprise) echo "--------------" echo "Space Shuttle Enterprise was the first Space Shuttle orbiter." echo "--------------" ;; pathfinder) echo "--------------" echo "Space Shuttle Orbiter Pathfinder is a Space Shuttle simulator made of steel and wood." echo "--------------" ;; *) echo "Error: Please try again (select 1..7)!" ;; esac done
Save and close the file. Run it as follows:
chmod +x selectshuttle.sh ./selectshuttle.sh
You can exiting the select loop statement either pressing Ctrl+C or by adding the exit option as follows:
#!/bin/bash # Set PS3 prompt PS3="Enter the space shuttle to get quick information : " # set shuttle list # exit option select shuttle in columbia endeavour challenger discovery atlantis enterprise pathfinder exit do case $shuttle in columbia) echo "--------------" echo "Space Shuttle Columbia was the first spaceworthy space shuttle in NASA's orbital fleet." echo "--------------" ;; endeavour) echo "--------------" echo "Space Shuttle Endeavour is one of three currently operational orbiters in the Space Shuttle." echo "--------------" ;; challenger) echo "--------------" echo "Space Shuttle Challenger was NASA's second Space Shuttle orbiter to be put into service." echo "--------------" ;; discovery) echo "--------------" echo "Discovery became the third operational orbiter, and is now the oldest one in service." echo "--------------" ;; atlantis) echo "--------------" echo "Atlantis was the fourth operational shuttle built." echo "--------------" ;; enterprise) echo "--------------" echo "Space Shuttle Enterprise was the first Space Shuttle orbiter." echo "--------------" ;; pathfinder) echo "--------------" echo "Space Shuttle Orbiter Pathfinder is a Space Shuttle simulator made of steel and wood." echo "--------------" ;; exit) echo "Bye!" break ;; *) echo "Error: Please try again (select 1..8)!" ;; esac done
Sample output:
1) columbia 3) challenger 5) atlantis 7) pathfinder 2) endeavour 4) discovery 6) enterprise 8) exit Enter the space shuttle to get quick information : 5 -------------- Atlantis was the fourth operational shuttle built. -------------- Enter the space shuttle to get quick information : 8 Bye!