首页 > 代码库 > Linux Shell脚本编写——使用结构化命令(三)
Linux Shell脚本编写——使用结构化命令(三)
for命令
for var in list
do
commands
done
代码2-1
root@lejian:/data# cat demo1 #!/bin/bash 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" root@lejian:/data# ./demo1 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 Colorado The last state we visited was California Colorado Wait, now we‘re visiting Connecticut
如代码2-1所示,如果想要打印的字符串包含空格,可以用""引号包装
for循环有时候会遇到特殊符号:
- 使用转义字符来将单引号转义
- 使用双引号来定义单引号的值
代码2-2
root@lejian:/data# cat demo2 #!/bin/bash echo "print I don‘t know if this‘ll work" for test in I don‘t know if this‘ll work do echo "word:$test" done echo "——————————————————————————————" for test in I don\‘t know if this\‘ll work do echo "word:$test" done echo "——————————————————————————————" for test in I don"‘"t know if this"‘"ll work do echo "word:$test" done root@lejian:/data# ./demo2 print I don‘t know if this‘ll work word:I word:dont know if thisll word:work —————————————————————————————— word:I word:don‘t word:know word:if word:this‘ll word:work —————————————————————————————— word:I word:don‘t word:know word:if word:this‘ll
for循环是根据空格来区分的,如果遇到包含空格的字符,可用双引号括起来
代码2-3
root@lejian:/data# cat demo3 #!/bin/bash for test in Nevada "New Hampshire" "New Mexico" "New York" do echo "Now going to $test" done root@lejian:/data# ./demo3 Now going to Nevada Now going to New Hampshire Now going to New Mexico Now going to New York
从变量读取列表
代码2-4
root@lejian:/data# cat demo4
#!/bin/bash
list="Alabama Alaska Arizona Arkansas California Colorado"
list=$list" Connecticut"
for state in $list
do
echo "Have you ever visited $state?"
done
root@lejian:/data# ./demo4
Have you ever visited Alabama?
Have you ever visited Alaska?
Have you ever visited Arizona?
Have you ever visited Arkansas?
Have you ever visited California?
Have you ever visited Colorado?
Have you ever visited Connecticut?
从命令中读取值
代码2-5
root@lejian:/data# cat state Alabama Alaska Arizona Arkansas California Colorado Connecticut root@lejian:/data# cat demo5 #!/bin/bash file=state for state in `cat $file` do echo "visit beautiful $state" done root@lejian:/data# ./demo5 visit beautiful Alabama visit beautiful Alaska visit beautiful Arizona visit beautiful Arkansas visit beautiful California visit beautiful Colorado visit beautiful Connecticut
修改字段分隔符,使用IFS=$‘;‘
代码2-6
root@lejian:/data# cat states Alabama;Alaska;Arizona;Arkansas;California;Colorado;Connecticut root@lejian:/data# cat demo6 #!/bin/bash file="states" IFS=$‘;‘ for state in `cat $file` do echo "visit beautiful $state" done root@lejian:/data# ./demo6 visit beautiful Alabama visit beautiful Alaska visit beautiful Arizona visit beautiful Arkansas visit beautiful California visit beautiful Colorado visit beautiful Connecticut
默认情况下,bash shell会把下列字符当做字段分隔符:
- 空格
- 制表符
- 换行符
用通配符读取目录
用for循环命令来自动遍历满是文件的目录,进行此操作时,必须在文件名或路径名中使用通配符。它会强制shell使用文件扩展匹配。文件扩展匹配是生成匹配指定的通配符的文件名或路径名的过程
代码2-7
root@lejian:/data# ls -l /home/software/apache-tomcat-1/ total 120 drwxr-xr-x 2 root root 4096 Nov 25 2014 bin drwxr-xr-x 3 root root 4096 Nov 26 2014 conf drwxr-xr-x 2 root root 4096 Nov 25 2014 lib -rw-r--r-- 1 root root 56977 Nov 3 2014 LICENSE drwxr-xr-x 2 root root 12288 Dec 3 01:21 logs -rw-r--r-- 1 root root 1397 Nov 3 2014 NOTICE -rw-r--r-- 1 root root 6779 Nov 3 2014 RELEASE-NOTES -rw-r--r-- 1 root root 16204 Nov 3 2014 RUNNING.txt drwxr-xr-x 2 root root 4096 Nov 25 2014 temp drwxr-xr-x 2 root root 4096 Nov 25 2014 webapps drwxr-xr-x 3 root root 4096 Nov 25 2014 work root@lejian:/data# ls -l /home/software/apache-tomcat-1/conf/ total 212 drwxr-xr-x 3 root root 4096 Nov 25 2014 Catalina -rw------- 1 root root 12374 Nov 3 2014 catalina.policy -rw------- 1 root root 6427 Nov 3 2014 catalina.properties -rw------- 1 root root 1577 Nov 3 2014 context.xml -rw------- 1 root root 3387 Nov 3 2014 logging.properties -rw------- 1 root root 6491 Nov 25 2014 server.xml -rw------- 1 root root 1744 Nov 3 2014 tomcat-users.xml -rw------- 1 root root 1846 Nov 3 2014 tomcat-users.xsd -rw------- 1 root root 163468 Nov 3 2014 web.xml root@lejian:/data# cat demo1 #!/bin/bash for file in /home/software/apache-tomcat-1/* /home/software/apache-tomcat-1/conf/* do if [ -d $file ] then echo "$file is a directory" elif [ -f $file ] then echo "$file is a file" else echo "$file doesn‘t exists" fi done root@lejian:/data# ./demo1 /home/software/apache-tomcat-1/bin is a directory /home/software/apache-tomcat-1/conf is a directory /home/software/apache-tomcat-1/lib is a directory /home/software/apache-tomcat-1/LICENSE is a file /home/software/apache-tomcat-1/logs is a directory /home/software/apache-tomcat-1/NOTICE is a file /home/software/apache-tomcat-1/RELEASE-NOTES is a file /home/software/apache-tomcat-1/RUNNING.txt is a file /home/software/apache-tomcat-1/temp is a directory /home/software/apache-tomcat-1/webapps is a directory /home/software/apache-tomcat-1/work is a directory /home/software/apache-tomcat-1/conf/Catalina is a directory /home/software/apache-tomcat-1/conf/catalina.policy is a file /home/software/apache-tomcat-1/conf/catalina.properties is a file /home/software/apache-tomcat-1/conf/context.xml is a file /home/software/apache-tomcat-1/conf/logging.properties is a file /home/software/apache-tomcat-1/conf/server.xml is a file /home/software/apache-tomcat-1/conf/tomcat-users.xml is a file /home/software/apache-tomcat-1/conf/tomcat-users.xsd is a file /home/software/apache-tomcat-1/conf/web.xml is a file
注:如果文件名或目录名包含空格,判断是否是文件还是目录需要使用双引号[ -d "$file" ]
C语言for循环风格
代码2-9
root@lejian:/data# cat demo2 #!/bin/bash for ((i=1;i<10;i++)) do echo "The next number is $i" done echo "——————————————————————————" for ((a=1,b=10;a<10;a++,b--)) do echo "$a - $b = `expr $a - $b`" done root@lejian:/data# ./demo2 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 —————————————————————————— 1 - 10 = -9 2 - 9 = -7 3 - 8 = -5 4 - 7 = -3 5 - 6 = -1 6 - 5 = 1 7 - 4 = 3 8 - 3 = 5 9 - 2 = 7
while命令
while命令允许定义一个要测试的命令,然后循环执行一组命令,只要定义的测试命令返回的是退出状态码0。它会在每个迭代的一开始测试test命令。在test命令返回非0退出状态码时,while命令会停止执行那组命令
while test command
do
other commands
done
代码2-10
root@lejian:/data# cat demo3 #!/bin/bash val=10 while [ $val -gt 0 ] do echo $val ((val--)) done root@lejian:/data# ./demo3 10 9 8 7 6 5 4 3 2 1
使用多个测试命令
while命令行允许定义多个测试命令,只有最后一个测试命令的退出状态码会被用来什么时候退出循环(注:多行命令必须用回车隔开)
代码2-11
root@lejian:/data# cat demo4 #!/bin/bash val=10 while echo $val [ $val -gt 0 ] do echo "This is inside the loop" ((val--)) done root@lejian:/data# ./demo4 10 This is inside the loop 9 This is inside the loop 8 This is inside the loop 7 This is inside the loop 6 This is inside the loop 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
until命令
until命令和while命令工作的方式完全相反。until命令要求指定一个通常输出非0退出状态码的测试指令。只有测试命令的退出状态码非0,bash shell才会指定循环中列出的那些命令,一旦测试命令返回了退出状态码0,循环结束
until test commands
do
other commands
done
代码2-12
root@lejian:/data# cat demo5 #!/bin/bash val=100 until [ $val -eq 0 ] do echo $val val=$[ $val - 25 ] done root@lejian:/data# ./demo5 100 75 50 25
嵌套循环
代码2-13
root@lejian:/data# cat demo6 #!/bin/bash for ((a=1;a<=3;a++)) do echo "Starting loop $a:" for ((b=1;b<=3;b++)) do echo "Inside loop:$b" done done root@lejian:/data# ./demo6 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
循环处理文件数据:
- 使用嵌套循环
- 修改IFS环境变量
循环处理文件数据
代码2-14
root@lejian:/data# cat passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin root@lejian:/data# cat demo1 #!/bin/bash IFS=$‘\n‘ for entry in `cat passwd` do echo "Values in $entry" IFS=$‘:‘ for value in $entry do echo " $value" done done root@lejian:/data# ./demo1 Values in root:x:0:0:root:/root:/bin/bash root x 0 0 root /root /bin/bash Values in daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin daemon x 1 1 daemon /usr/sbin /usr/sbin/nologin Values in bin:x:2:2:bin:/bin:/usr/sbin/nologin bin x 2 2 bin /bin /usr/sbin/nologin
控制循环:
- break命令
- continue命令
代码2-15
root@lejian:/data# cat demo2 #!/bin/bash for val in 1 2 3 4 5 6 7 8 9 do if [ $val -eq 6 ] then break fi echo "Iteration number:$val" done echo "The for loop is completed" root@lejian:/data# ./demo2 Iteration number:1 Iteration number:2 Iteration number:3 Iteration number:4 Iteration number:5 The for loop is completed
break n,n说明要跳出的循环层级。默认情况下n为1,表明跳出当前循环。如果设置为2,break命令就会停止下一级的外部循环
代码2-16
root@lejian:/data# cat demo3 #!/bin/bash for ((a = 1;a<5;i++)) do echo "Outer loop $a:" for ((b=1;b<100;b++)) do if [ $b -gt 6 ] then break 2 fi echo "Inner loop:$b" done done root@lejian:/data# ./demo3 Outer loop 1: Inner loop:1 Inner loop:2 Inner loop:3 Inner loop:4 Inner loop:5 Inner loop:6
continue命令
代码2-17
root@lejian:/data# cat demo4 #!/bin/bash for ((val=1;val<16;val++)) do if [ $val -gt 5 ] && [ $val -lt 11 ] then continue fi echo "Iteration number:$val" done root@lejian:/data# ./demo4 Iteration number:1 Iteration number:2 Iteration number:3 Iteration number:4 Iteration number:5 Iteration number:11 Iteration number:12 Iteration number:13 Iteration number:14 Iteration number:15
和break命令一样,continue n也允许通过命令参数指定要继续哪一级循环
代码2-18
root@lejian:/data# cat demo5 #!/bin/bash for ((a=1;a<6;a++)) do echo "Iteration $a:" for ((b=1;b<3;b++)) do if [ $a -gt 2 ] && [ $a -lt 5 ] then continue 2 fi val=$[ $a * $b ] echo " The result of $a * $b = $val " done done root@lejian:/data# ./demo5 Iteration 1: The result of 1 * 1 = 1 The result of 1 * 2 = 2 Iteration 2: The result of 2 * 1 = 2 The result of 2 * 2 = 4 Iteration 3: Iteration 4: Iteration 5: The result of 5 * 1 = 5 The result of 5 * 2 = 10
处理循环的输出
done命令后面可添加重定向输出,可将命令输出到文件中而不是屏幕上
代码2-19
root@lejian:/data# cat passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin root@lejian:/data# cat demo6 #!/bin/bash for file in `cat passwd` do echo "The file content:$file" done > text root@lejian:/data# ./demo6 root@lejian:/data# cat text The file content:root:x:0:0:root:/root:/bin/bash The file content:daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin The file content:bin:x:2:2:bin:/bin:/usr/sbin/nologin
done命令适用于将循环的结果管接到另一个命令,再重定向到文件或者屏幕,还可以使用其他命令显示到屏幕上
root@lejian:/data# cat demo7 #!/bin/bash for state in "North Dakota" Connecticut Illnois Alabama Tennessee do echo "$state is the next place to go" done | sort > text echo "This completes our travels" root@lejian:/data# ./demo7 This completes our travels root@lejian:/data# cat text Alabama is the next place to go Connecticut is the next place to go Illnois is the next place to go North Dakota is the next place to go Tennessee is the next place to go
Linux Shell脚本编写——使用结构化命令(三)