Appearance
更多结构化命令
for命令
bash
for var in list
do
commands
done
在每次迭代中,变量var会包含列表中的当前值。第一次迭代会使用列表中的第一个值,第二次迭代使用第二个值,以此类推,直到列表中的所有值都过一遍
和python中的迭代一样
读取列表中的值
读取自己定义的列表
bash
1 #!/bin/bash
2 for test in Alabama Alaska Arizona Arkansas California Colorado
3 do
4 echo The next state is $test
5 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test.sh
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
test会保留最后一次循环的值
读取列表的复杂值
bash
1 #!/bin/bash
2
3 for test in I don't know if this'll work
4 do
5 echo "word:$test"
6 done
7 #another example of how not to use the
8 for test in I don\'t know if "this'll" work
9 do
10 echo "word:$test"
11 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test2.sh
word:I
word:dont know if thisll
word:work
word:I
word:don't
word:know
word:if
word:this'll
word:work
会把存在的引号当做分割的符号, 可以使用转义字符, 或者使用另一种引号引起来
for循环假定所有的分割都使用的空格, 如果有的值中间存在空格要使用引号引起来
bash
1 #!/bin/bash
2 for test in Nevada "New Hampshire" "New Mexico" "New York" "North Carolina"
3 do
4 echo $test
5 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test3.sh
Nevada
New Hampshire
New Mexico
New York
North Carolina
从变量读取列表
把值存放在一份列表之中
bash
1 #!/bin/bash
2 list="Alabama Alaska Arizona Arkansas Colorado"
3 for test in $list
4 do
5 echo "Have you ever visted $test"
6 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test4.sh
Have you ever visted Alabama
Have you ever visted Alaska
Have you ever visted Arizona
Have you ever visted Arkansas
Have you ever visted Colorado
从命令读取值
生成列表中所需值的另外一个途径就是使用命令的输出。可以用命令替换来执行任何能产生输出的命令,然后在for命令中使用该命令的输出
bash
1 #!/bin/bash
2 file="state"
3 for state in $(cat $file)
4 do
5 echo "Visit beautiful $state"
6 done
# state文件
1 Alabama
2 Alaska
3 Arizona
4 Arkansas
5 Colorado
6 Connecticut
7 Delaware
8 Florida
9 Georgia
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test5.sh
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
更换字段的分隔符
环境变量IFS, 叫做内部字段分隔符, 定义了bash shell作为分隔符的一些列字符, 通常为
- 空格
- 制表符
- 换行符
要想只识别换行符, IFS=$'\n'
bash
1 #!/bin/bash
2 # reading values from a file
3 file="states"
4 IFS=$'\n'
5 for state in $(cat $file)
6 do
7 echo $state
8 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test6.sh
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticu
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
Visit beautiful New York
Visit beautiful New Hampshire
Visit beautiful North Carolina
最好再更改之前对IFS的值进行保存
bash
IFS.OLD=$IFS
IFS=$'\n'
<在代码中使用新的IFS值>
IFS=$IFS.OLD
可以设置多个分隔符, 只需要串起来
bash
IFS=$'\n':;"
使用换行符, 冒号, 分号, 双引号为分隔符
用通配符读取目录
可以使用for命令来遍历目录中的文件,
进行此操作时,必须在文件名或路径名中使用通配符。它会强制shell使用文件扩展匹配。
bash
1 #!/bin/bash
2 for file in /home/jiao/*
3 do
4 if [ -d "$file" ]
5 then echo "$file is a dictory"
6 elif [ -f "$file" ]
7 then echo "$file is a dictory"
8 fi
9 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test7.sh
/home/jiao/01_Python is a dictory
/home/jiao/公共的 is a dictory
/home/jiao/模板 is a dictory
/home/jiao/视频 is a dictory
/home/jiao/图片 is a dictory
/home/jiao/文档 is a dictory
/home/jiao/下载 is a dictory
/home/jiao/音乐 is a dictory
/home/jiao/桌面 is a dictory
/home/jiao/Makefile is a dictory
/home/jiao/snap is a dictory
在Linux文件名包含空格是合法的, 所以为了适应, 用引号括起来
也可以在for命令中列出多个目录通配符,将目录查找和列表合并进同一个for语句
bash
for file in /home/rich/.b* /home/rich/badtest
C语言风格的for语句
bash
for (( variableassignment ; condition ; iterationprocess ))
bash
1 #!/bin/bash
2 for (( i=1 ; i<10 ; i++ ))
3 do
4 echo "The next is $i"
5 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test8.sh
The next is 1
The next is 2
The next is 3
The next is 4
The next is 5
The next is 6
The next is 7
The next is 8
The next is 9
使用多个变量
也允许为迭代使用多个变量。循环会单独处理每个变量,你可以为每个变量定义不同的迭代过程。尽管可以使用多个变量,但你只能在for循环中定义一种条件
for (( a=1, b=10; a <= 10; a++, b-- ))
while命令
只要定义的测试命令的代码返回值是0, 就一直进行循环
while的基本格式
bash
while testcommand
do
othercommands
done
while命令中定义的test command和if-then语句中的格式一模一样, 可以使用任何普通的bash shell命令,或者用test命令进行条件测试
bash
1 #!/bin/bash
2 val1=10
3 while [ $val1 -gt 0 ] # 这里用的是test命令的中括号
4 do
5 echo $val1
6 val1=$[ $val1 - 1 ] # 这里使用的是浮点数计算时候讲的中括号
7 done
使用多个测试命令
while命令允许你在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环。
bash
1 #!/bin/bash
2 var1=10
3 while echo $var1
4 [ $var1 -ge 0 ]
5 do
6 echo "This is inside loop"
7 var1=$[ $var1 - 1 ]
8 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test10.sh
10
This is inside loop
9
This is inside loop
8
This is inside loop
7
This is inside loop
6
This is inside loop
5
This is inside loop
4
This is inside loop
3
This is inside loop
2
This is inside loop
1
This is inside loop
0
This is inside loop
-1
注意,每个测试命令都出现在单独的一行上
until命令
测试命令码不为0的时候进行循环, 不为0的时候退出循环
bash
until test command
do
other commands
done
bash
1 #!/bin/bash
2
3 var1=100
4 until [ $var1 -eq 0 ]
5 do
6 echo $var1
7 var1=$[ $var1 - 25 ]
8 done
嵌套循环
bash
10 for (( a = 1; a <= 3; a++ ))
11 do
12 echo "Start loop $a:"
13 for (( b=1; b<=3; b++ ))
14 do echo " Inside loop: $b"
15 done
16 done
循环处理文件数据
bash
1 #!/bin/bash
2
3 IFS.OLD=$IFS
4 IFS=$'\n'
5 for entry in $(cat /etc/passwd) # 这里已经把结果分割为多个值了
6 do
7 echo "Value in $entry -"
8 IFS=:
9 for value in $entry
10 do
11 echo " $value"
12 done
13 done
Value in jiao:x:1000:1000:jiao,,,:/home/jiao:/bin/bash -
jiao
x
1000
1000
jiao,,,
/home/jiao
/bin/bash
控制循环
- break
- continue
break
跳出单次循环
略
跳出内层循环
略
跳出外层循环
有时你在内部循环,但需要停止外部循环。break命令接受单个命令行参数值
bash
break n
n为1, 跳出挡圈循环, 2跳出下一层
bash
1 #!/bin/bash
2
3 for ((a=0;a<4;a++))
4 do
5 echo "Outer loop $a"
6 for ((b=1;b<100;b++))
7 do
8 if [ $b -gt 4 ]
9 then
10 break 2
11 fi
12 echo " Inner loop $b"
13 done
14 done
jiao@jiao-virtual-machine:~/桌面/linux-shell/13$ test14.sh
Outer loop 0
Inner loop 1
Inner loop 2
Inner loop 3
Inner loop 4
continue命令
也可以使用数字, 用来停止外部的循环
处理循环输出
bash
1 #!/bin/bash
2 for ((a=1;a<10;a++))
3 do
4 echo "The number is $a"
5 done > test.txt # 输出到一个文件中
6 echo "The command is finish"
- 同样使用于管道
bash
1 #!/bin/bash
2
3 for state in "North Dakota" Connecticut Illinois Alabama Tennessee
4 do
5 echo "$state is the next place to go"
6 done | sort
7 echo "This conplete our travel"
实例
查找可执行的文件
查找PATH下的所有可执行文件
bash
1 #!/bin/bash
2 IFS=:
3 for floder in $PATH
4 do
5 for file in $floder/*
6 do
7 if [ -x $file ]
8 then
9 echo " $file"
10 fi
11 done
12 done
创建多个用户账户
csv格式保存用户的id以及用户的名字
bash
1 #!/bin/bash
2
3 input="users.csv"
4 while IFS=',' read -r userid name # 下一
5 do
6 echo "add $userid"
7 useradd -c "$name" -m $userid
8 done < "$input"