1. for命令

for命令的基本格式

for VAR in LIST    #VAR为变量,LIST为指定队列
doCOMMAND        #当VAR存在时执行COMMAND
done

1.1 读取列表中的值

[root@localhost test]# vi test.sh
#!/bin/bash
#Basic for command
#
for test1 in Alabama Alaska Arizona Arkansas California Colorado
doecho The states is $test1
done
~
~
~
~
"test.sh" 7L, 133C written
[root@localhost test]# ./test.sh
The states is Alabama
The states is Alaska
The states is Arizona
The states is Arkansas
The states is California
The states is Colorado

从上述示例中可看出for命令会遍历list值列表,而且for循环执行完成后会将变量保持在循环的最后一个值。如下:

[root@localhost test]# vi test1.sh
#!/bin/bash
#Basic for command
#
for test1 in Alabama Alaska Arizona Arkansas California Colorado
doecho The states is $test1
done
echo the last states is $test1
~
~
"test1.sh" 8L, 164C written
[root@localhost test]# ./test1.sh
The states is Alabama
The states is Alaska
The states is Arizona
The states is Arkansas
The states is California
The states is Colorado
the last states is Colorado

1.2 读取列表中的复杂值

当list中存在单引号等特殊符号时,shell会自动把它当成命令的一部分处理,例如列表中包含 I don't know if this'll work  ,则单引号中的't know if this'会被当成一个赋值来处理,通常有以下两种解决方法:

(1)使用转移符\将'进行转移,例如:don\'t;

(2)使用""将这个值引起来,例如:"don't"

[root@localhost test]# vi test2.sh
#!/bin/bash
#another example of how not to use the for command
#
for test2 in I don\'t know if "this'll" work
do      echo "word:$test2"
done~
~
~
"test2.sh" [New] 8L, 139C written
[root@localhost test]# chmod o+x test2.sh
[root@localhost test]# ./test2.sh
word:I
word:don't
word:know
word:if
word:this'll
word:work

因为for在读取list中的变量时是已空格为分割的,如果list中的值包含空格的话,可以将这个变量用""引起来,这样for命令在调取变量时就会将包含空格的变量作为整体调用。

1.3 从变量中读取列表

for命令的也可以读取变量作为list

[root@localhost test]# vi test3.sh
#!/bin/bash
#
# Using a variable to hold the list
list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" Connecticut"
for state in $list
doecho "Have you ever visited $state"
done
~
~
~
"test3.sh" [New] 9L, 187C written
[root@localhost test]# chmod o+x test3.sh
[root@localhost test]# ./test3.sh
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 for命令从命令执行结果中读取变量值

[root@localhost test]# vi test4.sh
#!/bin/bash
#reading values from a file
#
file="states"                                    #将命令参数赋值给变量file
for states in $(cat $file)                       #使用命令替换
doecho "Visit beautiful $states"done
~
~
~
"test4.sh" 9L, 124C written
[root@localhost test]# cat states                #执行shell脚本中相同命令
labama
Alaska
Arizona
Arkansas
Colorado
Connecticut
Delaware
Florida
Georgia
[root@localhost test]# ./test4.sh                #执行脚本,脚本将命令执行结果作为list赋值给变量
Visit beautiful labama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia

for命令支持文件中的内容作为list,但是在变量赋值时需输入文件的绝对路径

1.5 更改字段分隔符

for命令中的list分隔符是通过环境便令IFS来决定的,通过支持:

(1)空格

(2)制表符

(3)换行符

我们可以在shell中通过修改IFS变量值来临时变更分隔符,例如在shell中设定 IFS=$'\n',表示将分隔符设置为换行符。这样shell脚本中就可以使用含有空格的词了。

[root@localhost test]# vi test4.sh
IFS.OLD=$IFS
#!/bin/bash
#reading values from a file
#
file="states"
IFS=$'\n'                                    #设置IFS为换行符
for states in $(cat $file)
doecho "Visit beautiful $states"done
~
~
"test4.sh" 10L, 134C written
[root@localhost test]# vi states             #在每个states上加上一个空格
labam a
Alask a
Arizon a
Arkansa s
Colorad o
Connecticu t
Delawar e
Florid a
Georgi a
~
~
~
"states" 9L, 86C written
[root@localhost test]# cat states
labam a
Alask a
Arizon a
Arkansa s
Colorad o
Connecticu t
Delawar e
Florid a
Georgi a
[root@localhost test]# ./test4.sh        #执行结果依然正常
Visit beautiful labam a
Visit beautiful Alask a
Visit beautiful Arizon a
Visit beautiful Arkansa s
Visit beautiful Colorad o
Visit beautiful Connecticu t
Visit beautiful Delawar e
Visit beautiful Florid a
Visit beautiful Georgi a

有时候我们需要临时修改IFS值,当执行完指定命令后IFS变量恢复默认值,通过使用如下方式:

IFS.OLD=$IFS
IFS=$'\n'
在变量中使用新的IFS值
IFS=$IFS.OLD

我们还可以根据实际情况来指定其他分割符,例如在/etc/passwd文件中分割符是:,我们可以将所有会用到的分隔符串起来即可:

IFS=$'\n':;"

上述可以将换行符、冒号、分号和双引号作为分隔符.

1.6 使用通配符读取目录

当使用for命令遍历目录中的文件时可以使用通配符

[root@localhost test]# vi test5.sh
#!/bin/bash
#iterate through all the files in a directory
#
for file in /root/*
doif [ -d $file ]thenecho $file is a directoryelif [ -f $file ]thenecho $file is a filefi
done
~
~
"test5.sh" 13L, 191C written
[root@localhost test]# ./test5.sh
/root/anaconda-ks.cfg is a file
/root/Desktop is a directory
/root/Documents is a directory
/root/Downloads is a directory
/root/initial-setup-ks.cfg is a file
/root/Music is a directory
/root/Pictures is a directory
/root/Public is a directory
/root/shadow is a file
/root/Templates is a directory
/root/test is a directory
/root/Videos is a directory

2. C语言风格的for命令

在C语言中通常用for命令的迭代特性做一个计数器,shell同样支持这个功能。

2.1 C语言的for命令

格式:for (( variable assignment(变量分配) ; condition(条件) ; iteration process(迭代方式) ))

例如:for (( a=1;a<10;a++))

[root@localhost test]# vi test6.sh
#!/bin/bash
#
for (( a=1;a<10;a++ ))
doecho $a
done
~
~
"test6.sh" 6L, 54C written
[root@localhost test]# ./test6.sh
1
2
3
4
5
6
7
8
9

2.2 在C语言风格的for命令中可使用多个变量

[root@localhost test]# vi test7.sh
#!/bin/bash
#
for ((a=1,b=10;a<=10;a++,b--))
doecho $a-$b
done
~
~
~
"test7.sh" 6L, 65C written
[root@localhost test]# ./test7.sh
1-10
2-9
3-8
4-7
5-6
6-5
7-4
8-3
9-2
10-1

3. while命令

while命令类似于if-then 和for命令的杂合体,当while中的定义的测试命令返回的值为0,则while命令会一直运行,直至测试命令返回值不为0时终止。

3.1 while命令基本格式

格式:

while TEST COMMAND
doCOMMAND
done

示例:

[root@localhost test]# vi test8.sh
#!/bin/bash
#while command test
#
var=10
while [ $var -ge 0 ]
doecho $varvar=$[ $var - 1 ]
done
~
~
~
"test8.sh" 9L, 100C written
[root@localhost test]# ./test8.sh
10
9
8
7
6
5
4
3
2
1
0

3.2 使用多个测试命令

特点:

(1)while可以执行多个测试命令

(2)while循环是否终止已while后最后一条命令的执行结果为准

(3)while的每条测试命令应独占一行

示例:

[root@localhost test]# vi test9.sh
#!/bin/bash
#testing a multicommand while loop
#
var=10
while echo $var[ $var -ge 0 ]
doecho "This is inside the loop"var=$[ $var-1 ]
done
~
~
~
"test9.sh" 10L, 145C written
[root@localhost test]# ./test9.sh
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
This is inside the loop
-1

4.until命令

until命令与while命令相反,当测试命令退出状态码返回值不为0时,bash shell才会执行循环中的命令。当测试命令退出状态码返回值为0时,则结束循环。

4.1 until命令格式

until TEST COMMAND
doCOMMAND
done

示例:

[root@localhost test]# vi test10.sh
#!/bin/bash
#Testing until command
var1=10
until [ $var1 -eq 0 ]
doecho var1 is $var1var1=$[ $var1 - 1 ]
done
~
~
~
"test10.sh" 8L, 114C written
[root@localhost test]# ./test10.sh
var1 is 10
var1 is 9
var1 is 8
var1 is 7
var1 is 6
var1 is 5
var1 is 4
var1 is 3
var1 is 2
var1 is 1

5.嵌套循环

特点:嵌套循环输出将已嵌套的循环的次方

示例:

[root@localhost test]# vi test11.sh
#!/bin/bash
#nesting for loops
for ((a=1;a<=3;a++))
doecho "starting loop:$a"for ((b=1;b<=3;b++))doecho "inside loop:$b"done
done
~                                                                                                      ~
"test11.sh" 10L, 141C written
[root@localhost test]# ./test11.sh
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

混用效果也一样

while和for混用示例:

[root@localhost test]# vi test12.sh
#!/bin/bash
#while and for
#
var=5
while [ $var -ge 0 ]
doecho "outer loop:$var"for ((a=1;a<=3;a++))doecho "inside loop:$a"donevar=$[ $var - 1 ]
done
~
~
"test12.sh" [New] 13L, 163C written
[root@localhost test]# ./test12.sh
outer loop:5
inside loop:1
inside loop:2
inside loop:3
outer loop:4
inside loop:1
inside loop:2
inside loop:3
outer loop:3
inside loop:1
inside loop:2
inside loop:3
outer loop:2
inside loop:1
inside loop:2
inside loop:3
outer loop:1
inside loop:1
inside loop:2
inside loop:3
outer loop:0
inside loop:1
inside loop:2
inside loop:3

until命令和while命令混用

[root@localhost test]# vi test13.sh
#!/bin/bash
# using until and while loopsvar1=3until [ $var1 -eq 0 ]
doecho "Outer loop: $var1"var2=1while [ $var2 -lt 5 ]dovar3=$(echo "scale=4; $var1 / $var2" | bc)echo " Inner loop: $var1 / $var2 = $var3"var2=$[ $var2 + 1 ]donevar1=$[ $var1 - 1 ]
done
~
~
"test13.sh" 17L, 280C written
[root@localhost test]# ./test13.sh
Outer loop: 3Inner loop: 3 / 1 = 3.0000Inner loop: 3 / 2 = 1.5000Inner loop: 3 / 3 = 1.0000Inner loop: 3 / 4 = .7500
Outer loop: 2Inner loop: 2 / 1 = 2.0000Inner loop: 2 / 2 = 1.0000Inner loop: 2 / 3 = .6666Inner loop: 2 / 4 = .5000
Outer loop: 1Inner loop: 1 / 1 = 1.0000Inner loop: 1 / 2 = .5000Inner loop: 1 / 3 = .3333Inner loop: 1 / 4 = .2500

6. 控制循环

6.1 break命令

break命令可以退出任意类型的循环

6.1.1 跳出单个循环

[root@localhost test]# vi test14.sh
#!/bin/bash
#Testing break
#
for var1 in 1 2 3 4 5 6 7 8 9 10
doif [ $var1 -eq 5 ]thenbreakfiecho $var1
done
echo "The for loop is completed"~
~
~
"test14.sh" 13L, 154C written
[root@localhost test]# ./test14.sh
1
2
3
4
The for loop is completed

6.1.2 跳出内部循环

示例:

[root@localhost test]# vi test15.sh
#!/bin/bash
#Testing break
#
for (( a=1; a<4; a++ ))
doecho "outer loop: $a"for (( b=1; b<100; b++ ))doif [ $b -eq 5 ]thenbreakfiecho "inner loop: $b"done
done
~
~
"test15.sh" 15L, 184C written
[root@localhost test]# ./test15.sh
outer loop: 1
inner loop: 1
inner loop: 2
inner loop: 3
inner loop: 4
outer loop: 2
inner loop: 1
inner loop: 2
inner loop: 3
inner loop: 4
outer loop: 3
inner loop: 1
inner loop: 2
inner loop: 3
inner loop: 4

6.1.3 跳出外部循环

[root@localhost test]# vi test16.sh
#!/bin/bash
#breaking out of an outer loop
#
for (( a=1; a<4; a++ ))
doecho "outer loop: $a"for (( b=1; b< 100; b++ ))doif [ $b -eq 5 ]thenbreak 2fiecho "inner loop: $b"done
done
~
~
~
"test16.sh" 15L, 203C written
[root@localhost test]# ./test16.sh
outer loop: 1
inner loop: 1
inner loop: 2
inner loop: 3
inner loop: 4

6.2 continue命令

特点:

(1)continue命令可以终止符合指定条件的循环,但是不会退出循环;

(2)当continue执行后,该循环中continue后面的命令将不会被执行;

(3)continue有跟break一样的特性,可以支持跳出多级循环,仅需要使用continue N,N指明循环数,默认为1.

continue常规示例:

[root@localhost test]# vi test17.sh
#!/bin/bash
#Testing continue command
#
for (( var1=1; var1<15; var1++ ))
doif [ $var1 -gt 5 ] && [ $var1 -lt 10 ]thencontinuefiecho "var1 is $var1"
done
~
~
~
"test17.sh" [New] 11L, 165C written
[root@localhost test]# chmod o+x test17.sh
[root@localhost test]# ./test17.sh
var1 is 1
var1 is 2
var1 is 3
var1 is 4
var1 is 5
var1 is 10
var1 is 11
var1 is 12
var1 is 13
var1 is 14

当continue执行后,该循环中continue后面的命令将不会被执行

[root@localhost test]# vi test.sh
#!/bin/bash
#improperly using the continue commmand in a while loop
var1=0
while echo "while iteration: $var1"[ $var1 -lt 15 ]
doif [ $var1 -gt 5 ] && [ $var1 -lt 10 ]thencontinuefiecho " inside iteration number :$var1 "var1=$[ $var1 + 1 ]
done
~
~
~
"test.sh" 13L, 260C written
[root@localhost test]# ./test.sh |more
while iteration: 0inside iteration number :0
while iteration: 1inside iteration number :1
while iteration: 2inside iteration number :2
while iteration: 3inside iteration number :3
while iteration: 4inside iteration number :4
while iteration: 5inside iteration number :5
while iteration: 6
while iteration: 6
while iteration: 6
while iteration: 6
while iteration: 6
while iteration: 6
while iteration: 6
while iteration: 6

continue有跟break一样的特性,可以支持跳出多级循环,仅需要使用continue N,N指明循环数,默认为1.

[root@localhost test]# vi test1.sh
#!/bin/bash
#continuing an outer loop
for (( a=1; a<5; a++ ))
doecho "iteration $a:"for (( b=1; b<3; b++ ))doif [ $a -gt 2 ] && [ $a -lt 4 ]thencontinue 2fivar3=$[ $a * $b ]echo "The result of $a * $b is $var3"done
done
~
~
"test1.sh" 15L, 247C written
[root@localhost test]# ./test1.sh
iteration 1:
The result of 1 * 1 is 1
The result of 1 * 2 is 2
iteration 2:
The result of 2 * 1 is 2
The result of 2 * 2 is 4
iteration 3:
iteration 4:
The result of 4 * 1 is 4
The result of 4 * 2 is 8

7. 处理循环的输出

可以通过在done后重定向文件,将执行结果输出给指定文件

示例:

[root@localhost test]# vi test2.sh
#!/bin/bash
#Testing output to file
#
for file in /etc/*
doif [ -d "$file" ]thenecho "$file is a directory"elseecho "$file is a file"fi
done > /root/test/output              #将结果输出至output文件
~
~
"test2.sh" 12L, 175C written
[root@localhost test]# ./test2.sh
[root@localhost test]# cat output
/etc/abrt is a directory
/etc/adjtime is a file
/etc/aliases is a file
/etc/aliases.db is a file
/etc/alsa is a directory
/etc/alternatives is a directory
/etc/anacrontab is a file
/etc/asound.conf is a file
/etc/at.deny is a file
/etc/at-spi2 is a directory
/etc/audisp is a directory
/etc/audit is a directory
/etc/avahi is a directory
/etc/bash_completion.d is a directory
/etc/bashrc is a file
/etc/binfmt.d is a directory
/etc/brltty is a directory
/etc/brltty.conf is a file

也可以将结果通过管道符| 作为参数输入给命令

示例:

[root@localhost test]# vi test3.sh
#!/bin/bash
#
#piping a loop to another command
#
for state in "North Dakota" Connecticut Illinois Alabama Tennessee
do echo "$state is the next place to go"
done | sort                     #将输出结果使用sort进行排序
echo "This completes our travels"
~
~
~
"test3.sh" [New] 8L, 204C written
[root@localhost test]# chmod o+x test3.sh
[root@localhost test]# ./test3.sh
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

8. 循环实例

8.1 在环境变量的目录中查找可执行文件

[root@localhost test]# vi test.sh
#!/bin/bash
#
IFS=:
for directory in $PATH
doecho "$directory:"for file in $directory/*doif [ -x $file ]thenecho "$file"fidone
done
~
~
~
"test.sh" 14L, 153C written
[root@localhost test]# ./test.sh |more
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/sbin/abrt-auto-reporting
/usr/sbin/abrt-configuration
/usr/sbin/abrtd
/usr/sbin/abrt-dbus
/usr/sbin/abrt-harvest-pstoreoops
/usr/sbin/abrt-harvest-vmcore
/usr/sbin/abrt-install-ccpp-hook
/usr/sbin/abrt-server
/usr/sbin/accept
/usr/sbin/accessdb
/usr/sbin/accton
/usr/sbin/addgnupghome
/usr/sbin/addpart
/usr/sbin/adduser
/usr/sbin/agetty
/usr/sbin/alsactl
/usr/sbin/alsa-info
/usr/sbin/alsa-info.sh
/usr/sbin/alternatives
/usr/sbin/anaconda
/usr/sbin/anacron
/usr/sbin/applygnupgdefaults
/usr/sbin/arp
/usr/sbin/arpd
/usr/sbin/arping
/usr/sbin/atd
/usr/sbin/atrun
--More--

8.2 使用脚本批量创建用户

[root@localhost test]# vi test.sh
#!/bin/bash
#process new user accounts
#
input="useradd.csv"              #useradd.csv为当前目录下创建的csv文件,格式为userid,name
while IFS=',' read -r userid name  #将分隔符设置为,使用read -r命令会使读取一行后自动换行
doecho "adding user $name"  #输出创建信息useradd -c $name -m $userid #创建用户
done < $input
~
~
"test.sh" 9L, 167C written
[root@localhost test]# ./test.sh
adding user 2000
adding user 2001
[root@localhost test]# cat useradd.csv
test1,2000
test2,2001

转载于:https://blog.51cto.com/mwdmwz/1954315

更多的结构化命令(第十三章)相关推荐

  1. 《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

    许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then     ...

  2. Shell脚本编程基础 三 使用结构化命令

    结构化命令允许我们改变程序执行的顺序,在某些条件下执行一些命令而在其他条件下跳过另一些命令. (1)使用if-then语句 结构化命令中,最基本的类型就是if-then语句,其格式如下: if com ...

  3. Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)

    1. 使用 if-then 语句 最基本的结构化命令就是if-then语句.if-then语句有如下格式. if command then ​ commands fi 或者 if command; t ...

  4. 使shell用结构化命令

    shell--使用结构化命令 使用结构化命令 知识内容: # 改变命令流 # 使用if-then逻辑 # 嵌套if-then # 测试条件 # 高级if-then功能 许多程序在脚本命令之间需要某些逻 ...

  5. 学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环

    目录 学习笔记:CentOS7学习之二十二: 结构化命令case和for.while循环 22.1 流程控制语句:case 22.2 循环语句 22.1.2 for-do-done 22.3 whil ...

  6. linux SHELL之结构化命令

    SHELL之使用结构化命令 使用if-then语句 Bash代码   if command then commands fi 如果if后面的命令退出状态码=0,那么就执行then 另外一种形式 Bas ...

  7. shell编程(七) : [shell基础] 使用结构化命令

    接上一篇文章Linux shell编程(六): 基本shell脚本 3.2 使用结构化命令 前面介绍的都是顺序执行的命令,有时需要按照逻辑顺序执行命令,这是就需要对命令命令施加一些逻辑流程控制,这样的 ...

  8. shell脚本中的结构化命令(if-then-else、case、for、while、until) 脚本中的循环控制

    1. 结构化命令 上一次我们学习了shell脚本的一些基础知识,包括环境变量.重定向.数学运算.退出脚本的方式等,想了解的可以戳这个: shell脚本基础 之前,在我们的示例shell脚本里,shel ...

  9. Linux shell 脚本结构化命令 if-then

    shell 脚本结构化命令 1. if-then 语句基本使用 if-then 语句的基本格式: if command thencommands elifcommands elsecommands f ...

最新文章

  1. 陆奇激动地对世界说,百度就是中国的谷歌
  2. Android开发之TextView高级应用
  3. Java中基本数据类型和Object之间的关系
  4. Vivo手机调试 logcat 信息一堆星号问题
  5. laydate组件 无法传值_Vue组件通信的几种方式
  6. 游戏寻路中 A* 算法的改进
  7. 企业云存储:为什么中大型企业偏爱自建私有云?
  8. 合并果子(Vijos P1097)
  9. 福州公交车与拖拉机相撞1人死亡
  10. php7 验证url格式,url的组成格式为
  11. 把chord下dbm_noauth做成静态库,提供接口
  12. GARFIELD@01-25-2005
  13. 连续特征离散化--汇总
  14. iframe调用父页面js方法_JS高级技巧
  15. 引用当前网站集下的样式文件
  16. 董洁经纪人挑拨离间,潘粤明称董洁经纪人插手婚姻
  17. 数据结构题集c语言版题目与答案,数据结构题集(C语言版)答案 - 严蔚敏编著...
  18. python mac地址_如何使用Python生成MAC地址
  19. idea主题插件网址
  20. KAKASI - 将日文转换为平假名/片假名/罗马音

热门文章

  1. python 导入包的路径_关于Python包导入的知识点你知道吗?
  2. 重装系统找不到固态_重装系统时找不到固态
  3. python为什么慢_python-为什么startswith比切片慢
  4. 智慧旅游建设方案_智慧灯杆及智慧交通设施建设方案
  5. MATLAB画图:改变坐标轴刻度的显示数值
  6. 数学建模 时间序列模型
  7. FPGA/IC技术交流2020
  8. HDLBits 系列(37)此系列关于独热码的题目的疑问?
  9. 【 FPGA 】序列检测器的Moore状态机实现
  10. 应用PlanAhead 进行布局规划