流程控制语句
控制语句,即用来实现对程序流程的选择、循环、转向和返回等进行控制的语句。Bash中的控制语句有几种控制语句?额,小编也没统计过,不清楚哎!!按照百度百科的分类(选择语句,循环语句,转向语句)总结了几个。然后看下吧!
一、选择语句
1、if……else……fi
格式:
(1)if CONDITION;then if-true-doing fi (2)if CONDITION;then if-true-doing else if-false-doing fi (3)if CONDITION;then if-true-doing elif CONDITION;then if-true-doing else if-false-doing fi
注:!CONDITION 条件相反
练习1:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型
脚本:if.sh
[root@centos bash]# cat if.sh #!/bin/bash # file=/data/test if [ -e $file ];then echo "$file exists." file $file else mkdir -p $file fi [root@centos bash]# ./if.sh [root@centos bash]# ls -d /data/test /data/test [root@centos bash]# ls -dl /data/test drwxr-xr-x. 2 root root 4096 Sep 19 16:35 /data/test [root@centos bash]# ./if.sh /data/test exists. /data/test: directory [root@centos bash]#
练习2:位置参数与命令引用练习,统计用户任意指定的普通文件的行数
[root@centos bash]# cat 1.sh #!/bin/bash if [ -f $1 ];then lines=$(wc -l $1|cut -d ' ' -f1) echo "the $1 have $lines lines." else echo "the $1 is not exists or not a com file." fi [root@centos bash]# ./1.sh /etc/grub.conf the /etc/grub.conf have 17 lines. [root@centos bash]# ./1.sh /etc/grub the /etc/grub is not exists or not a com file. [root@centos bash]#
练习3:特殊变量$#和$@使用,输出脚本参数信息
[root@centos bash]# cat 3.sh #!/bin/bash echo "you input $# parameters." echo "you input the parameters are $@." [root@centos bash]# ./3.sh 1 2 3 you input 3 parameters. you input the parameters are 1 2 3. [root@centos bash]#
补充知识点:
bash脚本与用户交互使用的命令read.
read [options] VAR...
-p “prompt” 提示信息
-t timeout 超时时间
练习4:熟悉read命令的用法,请用户交互输入用户名,并判断创建系统新用户
[root@centos bash]# cat read.sh #!/bin/bash read -p "plz input a new username:" -t 10 username if [ -z $username ];then echo "you input empt,the end." exit fi if id $username &> /dev/null; then echo "$username exists." else useradd $username echo "the new user $username was be added." fi [root@centos bash]# ./read.sh plz input a new username: you input empt,the end. [root@centos bash]# ./read.sh plz input a new username:centos the new user centos was be added. [root@centos bash]# id centos uid=500(centos) gid=500(centos) groups=500(centos) [root@centos bash]# ./read.sh plz input a new username:centos centos exists. [root@centos bash]#
练习5:判断给定的两个数值,孰大孰小;
[root@centos bash]# cat 5.sh #!/bin/bash # #read -p "plz input two integer:" -t 10 num1 num2 if [ $# -lt 2 ];then echo "your input parameters are less than 2.plz re-enter." exit 1 fi if [[ $1 =~ ^[0-9]+$ ]]&&[[ $2 =~ ^[0-9]+$ ]];then if [ $1 -gt $2 ];then echo "the max number is $1." echo "the min number is $2." else echo "the max number is $2." echo "the min number is $1." fi else echo "the number $1 or $2 is not a integer.at least have a string." fi [root@centos bash]# ./5.sh 3 2 the max number is 3. the min number is 2. [root@centos bash]# ./5.sh a 4 the number a or 4 is not a integer.at least have a string. [root@centos bash]# ./5.sh 2 your input parameters are less than 2.plz re-enter. [root@centos bash]# ./5.sh a your input parameters are less than 2.plz re-enter. [root@centos bash]#
2、case
简洁版多分支if语句,当if语句中有多个elif时可以使用case语句代替,语言更简洁容易理解。使用场景:判断某变量的值是否为多种情形中的一种时使用;
格式:
case $VARIABLE in PATTERN1) 分支1 ;; PATTERN2) 分支2 ;; PATTERN3) 分支3 ;; ... *) 分支n ;; esac
PATTERN可使用glob模式的通配符:
*: 任意长度的任意字符;
?: 任意单个字符;
[]: 指定范围内的任意单个字符;
a|b: 多选1;
练习6:脚本可接受四个参数
start: 创建文件/var/lock/subsys/SCRIPT_NAME
stop: 删除此文件
restart: 删除此文件并重新创建
status: 如果文件存在,显示为"running",否则,显示为"stopped"
#!/bin/bash file_name=$(basename $0) pfile="/data/test/$file_name" if [ $# -lt 1 ];then echo "Usage: $0 start|stop|restart|status." fi case $1 in start) touch $pfile if [ -f $pfile ];then echo "$file_name was started." else echo "$file_name start failed." fi ;; stop) rm -f $pfile if [ -f $pfile ];then echo "$file_name stop failed." else echo "$file_name was stoped." fi ;; restart) if ! [ -f $pfile ];then echo "$file_name is not running." else rm -f $pfile if [ -f $pfile ];then echo "$file_name restart failed." else touch $pfile if [ -f $pfile ];then echo "$file_name was restarted." else echo "$file_name restart failed." fi fi fi ;; status) if [ -f $pfile ];then echo "$file_name is running." else echo "$file_name is stop." fi ;; *) echo "Usage: $0 start|stop|restart|status." ;; esac
二、循环语句
1、for……do……done
格式:
(1)、for CONDITION;do
doing-loop
done
condition是决定for循环的次数,运行和退出循环的条件。他的形式有多种样式,下面是列举的几种类型:
1、List:可以罗列出变量具体的取值范围,枚举。例:
name in user1,user2,user3,user4
2、命令引用:如果是连续的数字可以引用命令seq,这里也可以是其他能够取出一组数据的命令。例:
i in `seq 1 100`
整数数字还可以写成{1...100},与seq命令效果相同。
3、还可以是已经定义好的数组,例:
a=(1,3,4,5,6,7)
i in ${a[*]}
4、或者取某一范围的值,例:
file in /var/log/*
练习7:求100以内所有偶数之和;
[root@centos bash]# ./6.sh 2550 [root@centos bash]# cat 6.sh #!/bin/bash declare -i sum for i in `seq 0 2 100`;do sum+=$i done echo $sum [root@centos bash]#
[root@centos bash]# cat 6.sh #!/bin/bash declare -i sum for i in {1..100};do if [ $[$i%2] -eq 0 ];then sum+=$i fi done echo $sum [root@centos bash]# ./6.sh 2550 [root@centos bash]#
练习8:显示/etc目录下所有普通文件列表,而后统计一共有多少个文件
[root@centos bash]# cat 7.sh #!/bin/bash declare -i conut=0 for file in /etc/*;do if [ -f $file ];then let conut++ echo $conut $file fi done [root@centos bash]# ./7.sh 1 /etc/adjtime 2 /etc/aliases …… 124 /etc/wgetrc 125 /etc/yp.conf 126 /etc/yum.conf [root@centos bash]#
练习9:写一个脚本
(1) 传递两个文本文件路径给脚本;
(2) 显示两个文件中空白行数较多的文件及其空白行的个数;
(3) 显示两个文件中总行数较多的文件及其总行数;
[root@centos bash]# cat 8f.sh #!/bin/bash space_lines1=$[$(grep '^$' $1|wc -l)+$(grep '^[[:space:]]\+$' $1|wc -l)] space_lines2=$[$(grep '^$' $2|wc -l)+$(grep '^[[:space:]]\+$' $2|wc -l)] if [ $space_lines1 -gt $space_lines2 ];then echo "File $1 have $space_lines1 space lines more than $2." else echo "File $2 have $space_lines2 space lines more than $1." fi ############################################################################### file_lines1=$(cat $1|wc -l) file_lines2=$(cat $2|wc -l) if [ $file_lines1 -gt $file_lines2 ];then echo "File $1 have $file_lines1 lines more than $2." else echo "File $2 have $file_lines2 lines more than $1." fi [root@centos bash]# ./8f.sh 5.sh 6.sh File 5.sh have 3 space lines more than 6.sh. File 5.sh have 21 lines more than 6.sh. [root@centos bash]#
练习10:写一个脚本,打印九九乘法表;
[root@centos bash]# cat 9.sh #!/bin/bash for i in {1..9};do for j in $(seq 1 $i);do if ! [ $i -eq $j ];then echo -n -e "${j}X${i}=$[$i*$j]\t" else echo -e "${j}x${i}=$[$i*$j]\t" fi done done [root@centos bash]# ./9.sh 1x1=1 1X2=2 2x2=4 1X3=3 2X3=6 3x3=9 1X4=4 2X4=8 3X4=12 4x4=16 1X5=5 2X5=10 3X5=15 4X5=20 5x5=25 1X6=6 2X6=12 3X6=18 4X6=24 5X6=30 6x6=36 1X7=7 2X7=14 3X7=21 4X7=28 5X7=35 6X7=42 7x7=49 1X8=8 2X8=16 3X8=24 4X8=32 5X8=40 6X8=48 7X8=56 8x8=64 1X9=9 2X9=18 3X9=27 4X9=36 5X9=45 6X9=54 7X9=63 8X9=72 9x9=81 [root@centos bash]# 简化 #!/bin/bash for i in {1..9};do for j in $(seq 1 $i);do echo -n -e "${j}X${i}=$[$i*$j]\t" done echo done
2、while/do……while
格式:
while CONDITION; do
循环体
控制变量的修正表达式
done
进入条件:当CONDITION为“真”;
退出条件:当CONDITION为“假”;
练习11:分别求100以内所有奇数之和,及所有偶数之和
[root@centos bash]# cat 11.sh #!/bin/bash declare -i sum=0 declare -i sum_1=0 declare -i sum_2=0 declare -i i=1 while [ $i -le 100 ];do if [ $[$i%2] -eq 0 ];then sum_1+=$i else sum_2+=$i fi sum+=$i let i++ done echo "the sum of numbers in 100 is $sum." echo "the sum of odd numbers in 100 is $sum_1." echo "the sum of even numbers in 100 is $sum_2."
3、Until
格式:
until CONDITION; do
循环体
循环控制变量的修正表达式
done
进入条件:当CONDITION为“假”时
退出条件:当CONDITION为“真”时
练习12:分别使用while和until循环实现添加10个用户:user1-user10
[root@centos bash]# cat 12.sh #!/bin/bash declare -i i=1 until [ $i -eq 11 ];do useradd user$i let i++ done [root@centos bash]# tail /etc/passwd haldaemon:x:68:68:HAL daemon:/:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin saslauth:x:498:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin centos:x:500:500::/home/centos:/bin/bash [root@centos bash]# chmod +x 12.sh [root@centos bash]# ./12.sh [root@centos bash]# tail /etc/passwd user1:x:501:501::/home/user1:/bin/bash user2:x:502:502::/home/user2:/bin/bash user3:x:503:503::/home/user3:/bin/bash user4:x:504:504::/home/user4:/bin/bash user5:x:505:505::/home/user5:/bin/bash user6:x:506:506::/home/user6:/bin/bash user7:x:507:507::/home/user7:/bin/bash user8:x:508:508::/home/user8:/bin/bash user9:x:509:509::/home/user9:/bin/bash user10:x:510:510::/home/user10:/bin/bash [root@centos bash]#
4、循环控制:
continue [n]:提前结束本轮循环,而直接进入下一轮;
break [n]:提前结束循环;
5、死循环:
始终满足执行条件,无法退出循环。这样的循环内,可以使用循环控制来跳出循环。
格式:
(1)while true; do
循环体
done
(2)until false; do
循环体
done
6、特殊的循环用法:
(1)while遍历文件的每一行
while read VARIABLE; do
循环体
done < /PATH/FROM/SOME_FILE
(2)For循环类C++用法
for ((expr1;expr2;expr3)); do
循环体
done
练习13:传递一个文本文件为参数给脚本,取出此文件的所有的偶数行给予显示,行前要显示行号;
[root@centos bash]# cat 13.sh #!/bin/bash grep -n '.' $1|cut -d: -f1|while read line_nu;do line=`sed -n "${line_nu}p" $1` if [ $[$line_nu%2] -eq 0 ];then echo $line_nu $line fi done [root@centos bash]# ./13.sh 12.sh 2 declare -i i=1 4 useradd user$i 6 done [root@centos bash]#
三、函数
把一段具有独立功能代码封装在一起,并给予命名;后续用到时,可直接通过给定函数名来调用整体代码;
函数作用:1、代码重用;2、模块化编程
函数的使用方法:
先定义:编写函数代码
后调用:给出函数名,还可按需传递参数
定义方法:
(1) function f_name {
函数体
}
(2) f_name() {
函数体
}
调用函数:
f_name [argu1, argu2, ...]
自定义函数状态返回值:
return [#]
0: 成功
1-255:失败
注意:函数代码执行时,一旦遇到return,函数代码终止运行,函数返回;