Shell Programming - structured command (2)

1 for command

The basic format for the command:

for var in list 
do
    commands 
done

In the parameter list, you need to provide a range of value iteration to use.

1.1 value reading list

example:

$ vim test1
#!/bin/bash
# testing the for variable after the looping
 for test in Alabama Alaska Arizona Arkansas California Colorado 
 do
     echo "The next state is $test" 
 done
 echo "The last state we visited was $test" 
 test=Connecticut 
 echo "Wait, now we're visiting $test"
 
 Results of the:
$ ./ test1
The next state is Alabama 
The next state is Alaska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado
The last state we visited was Colorado 
Wait, now we're visiting Connecticut

1.2 complex value read list

Here's an example:

$ vim badtest1
#!/bin/bash
# another example of how not to use the for command
 for test in I don't know if this'll work 
 do
      echo "word:$test" 
 done 
 
 result:
 $ ./ badtest1
 word:I 
 word:dont know if thisll 
 word:work

Why is it so? How to deal with? There are two ways:

  • Use escape character (slash) to escape the single quotation marks;
  • Double quotes used to define the value of single quotation marks.

After treatment shell script:

$ vim test2
#!/bin/bash
# another example of how not to use the for command
 for test in I don\'t know if "this'll" work 
 do
      echo "word:$test" 
 done
 
 result:
 $ ./ test2
 word:I 
 word:don't 
 word:know 
 word:if 
 word:this'll 
 word:work

Each value is used for loop space separated. If the data value contains spaces, this will lead to similar problems, so the above second approach (in quotation marks) methods can be used.

1.3 to read from a list of variables

Look at an example:

$ vim test4
#!/bin/bash
# using a variable to hold the list
 list="Alabama Alaska Arizona Arkansas Colorado" 
 list=$list" Connecticut"
 for state in $list 
 do
      echo "Have you ever visited $state?" 
 done
 
 result:
$ ./ test4
Have you ever visited Alabama? 
Have you ever visited Alaska? 
Have you ever visited Arizona? 
Have you ever visited Arkansas?
Have you ever visited Colorado?
Have you ever visited Connecticut?

1.4 values are read from the command

$ vim test5
#!/bin/bash
# reading values from a file
 file="states"
 for state in $(cat $file) 
 do
      echo "Visit beautiful $state" 
 done 
 
 $ cat states
Alabama 
Alaska
Arizona
Arkansas
Colorado
Connecticut
Delaware
Florida
Georgia
Results of the:
$ ./test5
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware 
Visit beautiful Florida 
Visit beautiful Georgia

1.5 Change field separator

IFS called internal field delimiter

IFS environment variable bash shell defines a set of characters as the field separator. By default, bash shell will be the following characters as field separators:

  • Blank
  • Tabs
  • Newline

If the bash shell to see any of these characters in the data, it will be assumed that this signals the start of a new list of data fields.

But we can temporarily change the value of the IFS environment variable in a shell script to limit the field delimiter character is treated as the bash shell. For example, if you want to change the value of the IFS, it can only identify a line break, you must do the following:

IFS = $ '\ n'

This statement will be added to the script, told bash shell ignores spaces and tabs in the data values. This method of use prior to a script, the following output is obtained.

$ vim test5b
#!/bin/bash
# reading values from a file
file="states" 
IFS=$'\n' 
for state in $(cat $file) 
do
     echo "Visit beautiful $state" 
done 

$ ./test5b
Visit beautiful Alabama 
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
Visit beautiful New York
Visit beautiful New Hampshire 
Visit beautiful North Carolina

In dealing with a large amount of script code that may be necessary to modify the value of IFS in one place, then ignore this amendment, we continue to use the default value of IFS elsewhere in the script. A reference security practices is to preserve the original value before changing IFS IFS, then restore it later. This technique can be achieved:

  IFS.OLD=$IFS   
IFS=$'\n'   
<Using the new IFS value tag >    
IFS = $ IFS .OLD

 This ensures that used in the subsequent operation of the script is the default value of IFS.

 

In addition, we can also do it, if to do is set the value of the IFS colon:

IFS=:

If you want to specify more IFS characters, as long as they are assigned to string together the line on the line.

IFS=$'\n':;"

This assignment will newline, colon, semicolon, and double quotation marks as field separators. How to use the IFS character to parse the data without any restrictions.

 

1.6 read directory with wildcards

$ vim test6 
#!/bin/bash 
# iterate through all the files in a directory 
 for file in /home/rich/test/* 
 do 
    if [ -d "$file" ]     
    then
            echo "$file is a directory"     
    elif [ -f "$file" ]     
    then
            echo "$file is a file"     
    be 
done 

$ ./test6 
/home/rich/test/dir1 is a directory 
/home/rich/test/myprog.c is a file 
/home/rich/test/myprog is a file 
/home/rich/test/myscript is a file 
/home/rich/test/newdir is a directory 
/home/rich/test/newfile is a file 
/home/rich/test/newfile2 is a file 
/home/rich/test/testdir is a directory 
/home/rich/test/testing is a file 
/home/rich/test/testprog is a file 
/home/rich/test/testprog.c is a file 

for command will traverse / home / rich / test / * output results. The code is tested each entry (using the square brackets method) with the test command, to see if it is a directory or file. for later can be connected to loop through a plurality of paths. Note that the judgment condition "$ file" with quotes around it, this is to avoid our directory and file names with spaces caused by mistaken for multiple files and error.

 

2 C language style for command

Example a: a single variable

$ vim test8
#!/bin/bash
# testing the C-style for loop
 for (( i=1; i <= 10; i++ )) 
 do
      echo "The next number is $i" 
 done 
 
 $ ./ test8
The next number is 1
The next number is 2
The next number is 3
The next number is 4
The next number is 5
The next number is 6
The next number is 7
The next number is 8
The next number is 9
The next number is 10

Example Two: using a plurality of variables

$ vim test9
#!/bin/bash
# multiple variables
 for (( a=1, b=10; a <= 10; a++, b-- )) 
 do 
     echo "$a - $b" 
 done 
 
 ./ $ test9
 1 - 10
2   - 9
3   - 8
4   - 7
5   - 6
6   - 5
7   - 4
8   - 3
9   - 2
10  - 1

 

3 the while command

while the command format is:

while test command 
do
   other commands 
done

key while the command is specified in the Test the Command exit status code must be run with the command cycle is changed. If the exit status does not change, while circulation will have been kept going.

$ vim test10
#!/bin/bash
# while command test
var1 = 5
while [ $var1 -gt 0 ] 
do
     echo $var1     
     var1=$[ $var1 - 1 ] 
done 

$ ./ test10
 5
4
3                                                        
2
1

Use multiple test command:

$ vim test11
#!/bin/bash                                                  
# testing a multicommand while loop
var1 = 5                                                            
while echo $var1       
           [ $var1 -ge 0 ] 
do
    echo "This is inside the loop"     
    var1=$[ $var1 - 1 ] 
done 

$ ./test11
5
This is inside the loop 
4
This is inside the loop
3
This is inside the loop 
2
This is inside the loop 
1
This is inside the loop
0
This is inside the loop
-1

while statement defines two test command.

while echo $var1  
                     [ $var1 -ge 0 ]

The first test simply shows the current value of the variable var1. The second test used to determine the value of the square brackets var1 variable. Inside the loop, echo statement displays a simple message, indicating that the loop is executed. Note that when you run this example of how the output end.

This is inside the loop -1

The while loop will be equal to 0 in the implementation of echo statement variables var1, then the value of the variables var1 minus one. The next test is performed command again, time for the next iteration. echo test command is executed and displayed var variables (the now smaller than 0). Test test until the shell command execution, whle cycle will stop.

 

4 an until command

Exactly the opposite way until command and command while working. until command requires you to specify a test command usually returns a non-zero exit status codes. Only test command exit status is not 0, the cycle will be performed bash shell command listed. Once the test command returns an exit status of 0, the cycle is over.

format:

until test commands 
do
    other commands 
done

The following is an example command until use.

$ vim test12
#!/bin/bash                                                   
# using the until command
var1 = 100                                                                 
until [ $var1 -eq 0 ] 
do
    echo $var1
    var1=$[ $var1 - 25 ] 
done 

$ ./test12
100
75                                                            
50
25

Use multiple test commands while the same.

 

5 nested loop

A simple example for a nested loop in a for loop:

$ vim test14
#!/bin/bash
# nesting for loops
 for (( a = 1; a <= 3; a++ )) 
 do
      echo "Starting loop $a:"     
   for (( b = 1; b <= 3; b++ ))     
   do
           echo "   Inside loop: $b"    
  done 
done

$ ./ test14
Starting loop 1:
    Inside loop: 1
    Inside loop: 2
    Inside loop: 3 
Starting loop 2:
    Inside loop: 1
    Inside loop: 2
    Inside loop: 3 
Starting loop 3:
    Inside loop: 1
    Inside loop: 2
    Inside loop: 3

Placed inside the loop for a while loop:

$ vim test15 
#!/bin/bash 
# placing a for loop inside a while loop 
var1 = 5  
while [ $var1 -ge 0 ] 
do
    echo "Outer loop: $var1"     
    for (( var2 = 1; $var2 < 3; var2++ ))    
    do 
       var3=$[ $var1 * $var2 ]       
        echo "  Inner loop: $var1 * $var2 = $var3"     
    done     
    var1 = $ [ $ var1 - 1 ]
done 

$ ./test15 
Outer loop: 5 
   Inner loop: 5 * 1 = 5 
   Inner loop: 5 * 2 = 10 
Outer loop: 4 
   Inner loop: 4 * 1 = 4 
   Inner loop: 4 * 2 = 8 
Outer loop: 3 
   Inner loop: 3 * 1 = 3 
   Inner loop: 3 * 2 = 6 
Outer loop: 2 
   Inner loop: 2 * 1 = 2 
   Inner loop: 2 * 2 = 4 
Outer loop: 1 
   Inner loop: 1 * 1 = 1 
   Inner loop: 1 * 2 = 2 
Outer loop: 0 
   Inner loop: 0 * 1 = 0 
   Inner loop: 0 * 2 = 0 

Mix until and while loops:

$ vim test16 
#!/bin/bash 
# using until and while loops 
var1 = 3  
until [ $var1 -eq 0 ] 
do
     echo "Outer loop: $var1"     
     var2=1     
     while [ $var2 -lt 5 ]     
     do
             var3=$(echo "scale=4; $var1 / $var2" | bc)        
             echo "   Inner loop: $var1 / $var2 = $var3"        
             var2=$[ $var2 + 1 ]     
    done 
    var1 = $ [ $ var1 - 1 ]
done 

$ ./ TEST16
Outer loop: 3 
    Inner loop: 3 / 1 = 3.0000 
    Inner loop: 3 / 2 = 1.5000 
    Inner loop: 3 / 3 = 1.0000     
    Inner loop: 3 / 4 = .7500 
Outer loop: 2     
    Inner loop: 2 / 1 = 2.0000 
    Inner loop: 2 / 2 = 1.0000 
    Inner loop: 2 / 3 = .6666 
    Inner loop: 2 / 4 = .5000 
Outer loop: 1 
    Inner loop: 1 / 1 = 1.0000 
    Inner loop: 1 / 2 = .5000 
    Inner loop: 1 / 3 = .3333 
    Inner loop: 1 / 4 = .2500 

 

6 loop processing file data

Usually you have to traverse the data stored in the file. This requires a combination of the two technologies have been talked about:

  • Nested loop
  • IFS modify environment variables

By modifying the IFS environment variable, you can force the command file for each line as a separate entry to deal with, even if there are spaces in the data as well. Once the file is extracted from a separate line may need to use re-circulated to extract the number of rows in

A typical example is a data processing / etc / passwd file. This requires you to traverse progressive / etc / passwd file, and the value of IFS variable to the colon, which can be separated from each data segment in each row of the:

#!/bin/bash
# changing the IFS value
IFS.OLD=$IFS 
IFS=$'\n' 
for entry in $(cat /etc/passwd) 
do
    echo "Values in $entry –"     
    IFS=:     
    for value in $entry     
    do
       echo "   $value"     
    done 
done

This script uses two different IFS values ​​to parse the data. The first value IFS parsed / etc / passwd file separate line. For the inner loop is then modified to the value of IFS colon, you allow individual values ​​from the parsed / etc line / passwd in.

 

7 control cycle

7.1 BREAK command

1 out of a single cycle

Examples for loop, of course, equally applicable to the break command while and until cycle:

$ vim test17
#!/bin/bash
# breaking out of a for loop
for var1 in 1 2 3 4 5 6 7 8 9 10 
do
    if [ $var1 -eq 5 ]    
    then 
          break    
    be    
    echo "Iteration number: $var1" 
done 
echo "The for loop is completed"

$ ./test17
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
The for loop is completed

2. out of the inner loop

In dealing with multiple loops, break command will automatically terminate the inner loop where you are.

3 out of the outer loop

Sometimes you inside the loop, but the need to stop the outer loop. break command accepts a single command line parameters:

break n

Where n specifies the level to get out of the loop. By default, n- 1 indicates that out of the current cycle. If you n set to 2, break the outer loop command will stop the next level.

$ vim test20
#!/bin/bash
# breaking out of an outer loop
for (( a = 1; a < 4; a++ )) 
do
    echo "Outer loop: $a"    
    for (( b = 1; b < 100; b++ ))    
    do
      if [ $b -gt 4 ]       
      then    
            break 2     
      be       
      echo "   Inner loop: $b"    
    done 
done 

$ ./test20
Outer loop: 1
   Inner loop: 1
   Inner loop: 2
   Inner loop: 3
   Inner loop: 4

7.2 the Continue command

command can continue to suspend advance a particular cycle command, but does not completely terminate the entire cycle. Conditions can be set not to execute a command in the shell internal cycle.

Continue command using a simple example for the loop:

$ vim test21
#!/bin/bash
# using the continue command
 for (( var1 = 1; var1 < 9; var1++ )) 
 do 
    if [ $var1 -gt 3 ] && [ $var1 -lt 6 ]    
    then   
        continue    
    be    
    echo "Iteration number: $var1" 
done 

$ ./test21
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 6
Iteration number: 7
Iteration number: 8

Similarly, continue commands have the same break as the other two in usage, we look

continue n

 

8 output process loop

In shell scripts, you can use a pipe to redirect output or cycle. This can be a processing command by adding after done command.

Example One:

for file in /home/rich/*  
do  
  if [ -d "$file" ]    
  then
      echo "$file is a directory"    
  elif  
      echo "$file is a file"    
  be 
done > output.txt

The results for the command shell will be redirected to output.txt file, rather than displayed on the screen.

Example Two:

$ vim test24
#!/bin/bash
 for state in "North Dakota" Connecticut Illinois Alabama Tennessee 
 do 
    echo "$state is the next place to go" 
 done | sort 
 echo "This completes our travels"
 
$ ./test24
Alabama is the next place to go
Connecticut is the next place to go
Illinois is the next place to go
North Dakota is the next place to go
Tennessee is the next place to go
This completes our travels

state value is not listed in the list of commands for a particular order. The output for the command passed sort command, which will change the output order for the result of the command. Run this script actually illustrates the results have been sorted within the script.

 

9 Examples

9.1 find the executable file

When you run a program from the command line when, Linux system searches a list of directories to find the corresponding file. These directories are defined in the PATH environment variable. If you want to find out which system executable files are available, only need to scan your PATH environment variable in all the directories on the line.

$ vim test25
#!/bin/bash
# finding files in the PATH
 IFS=: 
 for folder in $PATH 
 do
     echo "$folder:"    
     for file in $folder/*    
     do   
         if [ -x $file ]       
         then     
              echo "   $file"       
          be    
     done 
done

9.2 to create multiple user accounts

You do not enter useradd command manually for each new user account needs to be created, but may need to add a new user account on a text file, and then create a simple script for processing. The format of this text file is as follows:

userid,name

The first entry is your new user account to the selected user ID. The second entry is the user's full name. Between two values ​​separated by a comma, thus forming a file format called comma-separated values ​​(or .csv).

$ vim test26
#!/bin/bash
# process new user accounts
input="users.csv"
while IFS=',' read -r userid name 
do
  echo "adding $userid"   
  useradd -c "$name" -m $userid 
done < "$input"

This script must be run as the root user, because useradd command requires root privileges.

Guess you like

Origin www.cnblogs.com/ericz2j/p/12045569.html