Bash编程之流程控制

Bash作为一种过程式编程语言,拥有一套流程控制体系,可完成选择执行,循环执行功能。下面分别介绍if/else,case,select,for,while/until等语法的使用。

Bash作为一种过程式编程语言,拥有一套流程控制体系,可完成选择执行,循环执行功能。下面分别介绍if/else,case,select,for,while/until等语法的使用。

一、选择执行

1、if语句

根据条件判断来选择执行哪个分支;if语句分为三种形式

1) 单分支

2) 双分支

3) 多分支

(1) 单分支

语法:

if condition;then          #命令不能和then写在一行
    command...
fi                          #if语句结束标志

condition 可以是条件测试:test,[ ],[[ ]];也可是一条命令。根据状态码来判断,0为true,其他为false。为true则执行then后面的语句,为false则不执行。

(2)双分支

语法:

if   condition;then
    command...
else
    command...
fi

判断condition的真假,为true执行then后面语句,为false则执行else后面语句

Bash的if分支语句不能为空,所以else后面的语句为空的话,else必需省略,则变为单分支形式。

例子,创建一个脚本,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息。

#!/bin/bash

[ -z $1 ]&&echo no user name&&exit       #判断传入参数是否合法
if id $1 &>/dev/null;then                #使用id 命令判断用户是否存在
        echo $1 already exist
        exit
else
        useradd $1
        echo user $1 create complete
        echo `id -a $1`
fi

(3)多分支

语法:

if condition1;then
    command...          #分支1
elif condition2;then
    command...          #分支2
elif condition3;then
    command...          #分支3

...                     #分支N

else
    command...          #其他情况,可省略
fi

执行逻辑:条件依次判断,当遇到条件为真时,执行其分支,然后退出if;如果所有条件都为假时,执行else分支,退出if。

例子,编写一个脚本,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

#!/bin/bash

[ ! -e $1 ]&&echo no such file &&exit

if [ -d "$1" ];then
        echo "`basename $1` is a directory"
elif [ -L "$1" ];then
        echo "`basename $1` is a symblic link"
elif [ -f "$1" ];then
        echo "`basename $1` is a regular file"
else
        echo "`basename $1` is an other type file"
fi

2、case语句

语法:

case  ${var}  in
part1)
    command...
    ;;                #分支结束符
part2)
    command...
    ;;
part3)
    command...
    ;;
*)
    command...
    ;;
esac                #case语句结束符

case语句在字符串判断上,可以替代if复杂的语句结构。

part判断,支持glob风格通配符:

? 代表一个任意字符

* 代表任意长度字符

[] 指定范围内一个字符

| 或操作符

例子,编写一个脚本,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息。

#!/bin/bash

read -p "please choose yes or no ? " input

case $input in
y|Y|[yY][eE][sS])            #可以支持判断模糊输入
        echo you answer yes
        ;;
n|no|[nN][oO])
        echo you answer no
        ;;
*)
        echo you answer other
        ;;
esac

二、循环执行

1、for语句

for语句适合执行列表遍历形式的循环。

语法:

for var in List;do

    command...
    
done

执行机制:依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束。

List给出形式:

(1)直接给出

for var in root mysql ftp;do    #分隔符为空格
...

(2) 整数列表:

        (a) {start..end}
        (b) $(seq [start [step]] end)

(3) 返回列表的命令

        $(COMMAND)

(4) 使用glob,如:*.sh

(5) 变量引用;

        $@, $*

#!/bin/bash         #ping IP 192.168.0.0 到 192.168.255.255 主机在线情况

for ip in 192.168.{0..255}.{0..255}
do
	if ping -W1 -c1 $ip &>/dev/null;then
		echo $ip is reachable
	else
		echo $ip is unreachable
	fi
done

for循环的特殊格式:

和c语言中for循环相同的格式,适合计数形式的循环。

语法:

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式));do          #括号中两个分号
    command...
done

 控制变量初始化:仅在运行到循环代码段时执行一次

 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

#!/bin/bash                # 使用for循环实现1...100加和
for ((i=1;i<=100;i++));do
    let sum+=i
done
echo $sum

2、while语句

语法:

while condition; do
    
    command...
    
done

condition:循环控制条件,进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环

#!/bin/bash                #使用while循环实现1到100加和
n=1                        
while [ $n -le 100 ]; do      
	((sum+=n))
	((n++))            #条件控制变量修正
done
echo $sum

while循环的特殊用法

用于实现遍历文件的每一行,根据取到的值进行其他操作。这是for语句做不到的。

语法:

while read line; do
    command...
done < /PATH/FROM/SOMEFILE

依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line。

#!/bin/bash                #遍历passwd文件,给用户添加备注信息

while read line;do
	user=`echo $line|cut -d: -f1`        #获取每一行中的用户名
	gecos=`echo $line|cut -d: -f5`
	if [ -z "$gecos" ];then
		chfn -f $user -p '62985600' $user &>/dev/null \      #给获取到的用户添加备注
		&&echo "GECOS of $user has changed"\
		||echo "GECOS of $user failed to change"
	fi
done < /etc/passwd

3、until语句

until语句与while语句形式相同,但是进入循环和退出循环的条件恰恰相反。

语法:

until condition; do
    
    command...
    
done

condition:循环控制条件,进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“false”,则执行一次循环;直到条件测试状态为“true”终止循环。

#!/bin/bash                #使用until实现1到100加和
n=1
until [ $n -gt 100 ]; do    #条件判断为直到n>100停止循环
	((sum+=n))
	((n++))
done
echo $sum

4、循环控制语句

控制语句用来提前结束一次循环,或者直接退出循环。

(1)continue

continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

#!/bin/bash
i=1
while [ $i -le 3 ];do
    echo ------------
    let i++
    continue
    echo ************
done

#执行结果,echo ** 在continue后面,永远不会被执行
------------
------------
------------

(2)break

break [N]:提前结束第N层循环,最内层为第1层

#!/bin/bash
i=1
while [ $i -le 3 ];do
    echo ------------
    let i++
    break
    echo ************
done

#执行结果,当打印第一次----后,遇到break标志,直接退出循环
------------

5、select语句

语法:

select var  [in List];do        #in List 可省略,使用位置变量传参
    command...
done

select语句主要用于创建菜单,按数字排列的菜单项将显示在标准输出上,并显示PS3提示符,等待输入,并且用户输入的内容由内置变量REPLY记录。

select循环是个死循环,循环体中加入break命令退出循环,经常配合case使用。

例子,

#!/bin/bash                          #脚本如下

PS3='which one would you like?'      #定义PS3提示符
select fruit in apple banana orange;do
case $fruit in
apple)
        echo "$fruit values 2\$/kg"
        break
        ;;
banana)
        echo "$fruit values 1\$/kg"
        break
        ;;
orange)
        echo "$fruit values 0.5\$/kg"
        break
        ;;
esac
done

[fly@centos7 shell]$ ./select.sh    #执行展示
1) apple
2) banana
3) orange
which one would you like?2
banana values 1$/kg
[fly@centos7 shell]$

原创文章,作者:cutemsyu,如若转载,请注明出处:http://www.178linux.com/37945

(0)
cutemsyucutemsyu
上一篇 2016-08-21
下一篇 2016-08-21

相关推荐

  • LVS入门

    随着互联网进入寻常百姓家,网络流量愈来愈大,大规模的网路访问如果都使用一个服务器提供服务,那么网络通讯注定会拥堵不堪。为了解决这些问题,达到使网络流量均衡地分散到各个服务器上的目的,一些技术大牛发明了LVS负载均衡技术。   LVS简介   LVS(Linux Virtual Server)即为Linux虚拟服务器,使由章文嵩博士主导开发…

    Linux干货 2017-05-09
  • nginx基本功能学习

    一、NGINX介绍: Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:            作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 …

    Linux干货 2015-12-19
  • 初入命令世界

    一、inode节点号         在linux中,每一个文件都有唯一的inode号,inode号也是系统识别的唯一编码,而文件名仅仅是为了使用者区分辨认, inode (index node )表中包含文件系统所有文件列表 一个节点(索引节点)是在一个表项,包含有关…

    2017-05-26
  • 使用ext_skel和phpize构建php5扩展

    首先声明:我们要构建的是扩展或者模块名为hello_module.该模块提供一个方法:hello_word. 1、php环境的搭建 我们一般使用源码包编译安装,而不是binary包安装。因为使用PHP的二进制分发包安装有些冒险,这些版本倾向于忽略./configure的两个重要选项,它们在开发过程中很便利: 第一个–enable-debug。这个…

    Linux干货 2015-05-28
  • Bonding多块网卡绑定同一IP地址

    Bonding多块网卡绑定同一IP地址 就是将多块网卡绑定同一IP地址对外提供服务,可以实现高可用或者负载均衡。当然,直接给两块网卡设置同一IP地址是不可能的。通过bonding,虚拟一块网卡对外提供连接,物理网卡的被修改为相同的MAC地址。 一共有七种模式这里提供三种常用的:   一、Mode 0 (balance-rr)  轮转( Round-robin…

    Linux干货 2016-09-07
  • grep简述

    grep(Globel Search Regular Expression and Printing out the line) 它能使用正则表达式搜索文本,并把匹配的行打印出来。 grep包括grep、egrep和fgrep。 egrep表示扩展的grep,相比grep支持更多的匹配模式, “grep -E”相当于egrep。 fgrep是fast gre…

    2017-04-06

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-21 22:24

    文章对各循环语句语法进行了梳理,通过脚本加深了自己对各语句的认识。关于课后练习需要认真完成,老师选的课后练习,都是笔试中常见的,也是很经典的。