shell 顺序.选择.循环

顺序结构

顺序结构定义

1.shell 程序流程控制结构三大结构
1)顺序结构
2)选择结构
3)循环结构

2.顺序结构的定义
顺序结构的程序设计是最简单的一种结构,它的执行顺序是自上而下,依次执行,因此,我们只要按照解决问题的思路依次编写程序即可。

顺序结构执行的流程图:

这里写图片描述

顺序结果的编写流程以及注意事项

1.顺序结构程序编写流程
1)编辑脚本文件,以#!/bin/sh 开头;

#!/bin/sh是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面跟的是此解释此脚本的shell的路径。其实第一句的#!是对脚本的解释器程序路径,脚本的内容是由解释器解释的,我们可以用各种各样的解释器来写对应的脚本。

2)编写业务程序,顺序编写语句块1、语句块2、语句块3 。

2.掌握常见的系统变量的含义:
这些系统变量通常用与命令行参数的获取。

变量名说明
$#不包括命令在内的命令行参数的数目
$*命令行所有参数组成的字符串
$@命令行所有参数组成的字符串
$nn为数字,$0表示命令名称,$1表示命令第一个参数,以此类推
$?上一个命令的返回值,如果正常退出则返回0,反之为非0值
$$当前进程的进程号 PID
%!后台运行的最后一个进程的进程好PID

注意:有时候需要获取到参数的个数,以及所有参数的内容。

使用方法:

/bin/sh analyse_server.sh $server_ip 
[liu@WLJY01 ~]$ sh analyse_server.sh 192.168.1.1 192.168.1.2 192.168.1.3 .....

3.掌握常见的环境变量
这些变量与系统工作环境有关

变量名说明变量名说明
HOME当前用户主目录PWD用户的当前目录
PATH命令搜索路径UID当前用户标识符
LOGNAME用户登录名TERM终端的类型
PS1第一命令提示符,是#或$SHELL用户的shell类型以及路径
PS2第二命令提示符,默认是>HISFILE存储历史命令的文件

4.掌握用户变量的定义和引用
用户自己定义变量的定义与引用。
理解:

a=“this is a string”
echo $a
echo ${a} 
# 这两个输出的区别是什么? 没有区别
echo ${a}bc
echo $abc
# 第二个由于没有abc的变量,输出为空,不同于第一个

交互式输入与输出程序编写

1.交互式输入与输出

read 命令读取标准输入设备的一行,到新行换行符前的字符作为终止,把读到的字符赋值给变量。
可以结合echo 一起实现读取并输出的功能。

2.顺序结构 交互式输入与输出程序演练

1)程序功能,读取一个IP地址串,然后输出该IP地址。

[liu@WLJY01 myscript]$ cat read-echo.sh 
#!/bin/sh
# 接受输入并输出IP地址
echo "please input your ipaddress"
read  ipaddr
echo "my ip address is $ipaddr"

2) 给出输入提示的read用法

read -p “提示信息:” myaddr

[liu@WLJY01 myscript]$ cat read-echo2.sh 
#!/bin/sh
# 接受输入并输出
now_time=`date +%F,%H:%M:%S`
read -p "please input your username:" username
read -p "please input password:" password
password_md5=$(echo $password|md5sum|awk '{print $1}')
echo "$now_time,系统为您生成的用户名和密码为:$username/$password_md5"

awk是用来提取列的主要工具;
{print $1}就是将某一行(一条记录)中以空格为分割符的第一个字段打印出来

echo "aa bb cc" | awk -F '{print $1}' 
#结果就是aa,意思是把字符串按空格分割,取第一个

选择结构

选择结构的定义

1.选择结构的定义
选择结构是程序中带有判断的一种逻辑结构,只有符合一定的条件,程序体才会被执行

2.Linux shell 选择结构分类
1)if-then控制结构
2)case–esac控制结构

if then 控制结构

1.if then 控制结构的分类

1.单分支if结构,此类单分支结构,当条件满足的时候,就会执行then后面的语句,不满足就直接退出判断语句。

 if [ 条件 ];then
    语句...
 fi   

程序演练,判断一个用户是否存在,存在则输出这个用户存在信息。

#!/bin/sh
#if-then 单分支控制结构演练

id apache  # 查找id为apache的用户信息
if [$? -eq 0]   #查找是否成功
    then
         echo "apache user exists!"
fi

[liu@WLJY01 myscript]$ cat if-then-dan.sh  
[root@WLJY01 myscript]# sh if-then-dan.sh  apache
uid=48(apache) gid=48(apache) groups=48(apache)
apache user exists!

2.双分支if结构,当条件满足的时候就会运行then后面的语句,条件不满足的时候就运行else后面的语句。

语法:

  if [ 条件 ];then
          语句1...
  else
          语句2...
   fi

程序演练:判断第一个系统参数用户是否存在,存在则输出用户的UID ,否则创建该用户,并且输出这个用户的UID。

#!/bin/sh
#if-then双分支结构演练

id=$(id -u $1) #显示用户信息,第一个参数$1是用户名称,结果引用传给id变量
if [$? -eq 0]
    then
        #存在该用户,输出他的id
        echo "$1 user already exist,uid is $id"
     else
         #不存在这个用户,则创建这个用户
        useradd $1
        id=$(id -u $1)
        echo "$1 user already exist,uid is $id"
fi

[root@WLJY01 myscript]# cat if-then-shuang.sh 
[root@WLJY01 myscript]# sh if-then-shuang.sh liutao
liutao user already exist , uid is 503

3.嵌套if结构,当条件满足条件1,则执行then后面的语句,当条件再满足条件2,则执行then后面的语句,不满足条件2,则退出;当条件不满足条件1,则执行else后面的语句。

if [ 条件1 ];then
 if [ 条件2 ];then
                 语句...
          else
                语句.....
           fi
  else
             语句....
   fi

程序演练:首先判断运行脚本的系统参数有多少个,如果参数个数不等于1,则提示参数输入错误,否则,判断输入的用户是否存在,存在则输出用户的UID ,不存在,则创建该用户,并且输出这个用户的UID。

#!/bin/sh
#if-then嵌套结构演练
#Usage:sciptfile username

if [$# -ne 1] #如果输入的参数个数不等于1
    then
        echo "参数输入错误,只能输入一个参数"
    else
        id=$(id -u $1) # $()跟``一样,都是执行小括号内的Linux命令
        if [$? -eq 0]
             then
                 #存在该用户,输出他的id
                 echo "$1 user already exist,uid is $id"
              else
                #不存在这个用户,则创建这个用户
               useradd $1
               id=$(id -u $1)
               echo "$1 user already exist,uid is $id"
          fi
fi


[root@WLJY01 myscript]# sh if-then-qiantao.sh liutao
liutao user already exist , uid is 503
[root@WLJY01 myscript]# sh if-then-qiantao.sh liutao5
id: liutao5: No such user
liutao5 is created ,and uid is 506

case esac控制结构

case语句适用于需要进行多重分支的应用情况,它也是选择结构中常用的一种控制结构。

case分支语句的格式如下

case $变量名 in # 严格掌握其语法 
 模式1# 右括号不能省
 命令序列1
 ;;        # 两分号不能省
 模式2)
 命令序列2
 ;; 
  *)
  默认执行的命令序列 
  ;; 
 esac       #结尾反写case表示结束。

程序演练:
用户从键盘输入一个字符,判断该字符是字母、数字、还是其他字符,并给出其提示信息。

#!/bin/sh
#case-case分支结构演练

read -p "请输入一个字符,然后按回车" key  
#先显示提示符,然后将用户输入的内容赋值给key变量
case $key in
[0-9])
    echo "你输入的是数字"
    echo "数字是:$key"
;;
[a-z][A-Z])
    echo "你输入的是字符"
    echo "字符是:$key"
;;
*)
    echo "你输入的是特殊符号"
    echo "特殊符号是:$key"
;;
esac


[liu@WLJY01 myscript]$ cat case_1.sh 
[liu@WLJY01 myscript]$ sh case_1.sh 
请输入一个字符,然后按回车3
你输入的是数字 
数字是:3
[liu@WLJY01 myscript]$ sh case_1.sh 
输入一个字符,然后按回车R
你输入的是字符
字符是:R
[liu@WLJY01 myscript]$ sh case_1.sh 
请输入一个字符,然后按回车%
你输入的是特殊符号
特殊符号是:%

循环结构

for循环结构

for 循环结构分类:
for 循环结构与c语言的循环结构类似,分为如下几种:

1.编历/列表式循环结构
语法如下:

for variable in list
       do
           statement
       Done

实际环境操作:

1)用seq产生一个序列范围,来控制编历的次数。
seq命令产生一个数到另一个数之间的所有整数) seq 10 20

#/bin/sh
#演练for循环之遍历列表结构用法
for i in $(seq 3)  #连续序列
#for i in $(seq 1 3)
    do
        echo "output $i ..."
    done

[liu@WLJY01 myscript]$ ls   for_1_1.sh 
[liutaostdio@WLJY01 myscript]$ sh for_1_1.sh 
output 1 ...
output 2 ...
output 3 ...

2)命令序列不是连续的情况,可以自定义来处理。

#!/bin/sh
#演练for循环之遍历列表结构用法
for mydir in A B C E J  #非连续序列
    do
        mkdir -v $mydir  # -v 为每个目录显示提示信息。
        chmod 755 $mydir
    done

[liutaostdio@WLJY01 myscript]$ sh for_1_2.sh 
mkdir: created directory `A'
mkdir: created directory `E'
mkdir: created directory `J'

2.C语言风格的循环结构
当for循环的条件为真时,执行循环体中的语句,语法如下:

for (( expr1;expr2;expr3 ))     # (()),注意
do
     statement
done

创建一年中1月至12月所使用的数据库,将调用统计的结果插入到相应的月份中 。

#!/bin/sh
#演练C程序式的for循环结构
#提前创建一年中1月-12月所使用的数据库,将调用统计的结果插入到相应的月份中。
for ((month=1;$month<=12;month++))
do 
    echo "create database analyse_$month..."
    sleep 1  #停顿1秒
    #mysql -e "create database analyse_$month"
    #统计结果入相应的月份库中
    #...
done

[liutaostdio@WLJY01 myscript]$ sh for_2_1.sh 
create database analyse_1...
create database analyse_2...
create database analyse_3...
create database analyse_4...

While循环结构

1.while循环的结构

当while 条件表达式为真时,执行循环体中的语句,语法如下

while expression   
do 
statement
done

2.while 循环控制结构又分为两种
1.while [] 结构,此时注意while 后要跟空格,否则会报错。
如: while [ $i -le 10 ],while(())结构,不用跟空格,如:while((i<10))

1)用while [] 结构控制循环的次数,输出相关的变量

#!/bin/sh
#演练while []循环结构
i=1
while [ $i -le 10] #注意[]前的空格,i<=10
    do
        echo $i
        let i++;
    done

[liu@WLJY01 myscript]$ sh  while_1_1.sh
1
2
3
.....

2)用while(())结构控制循环的次数,输出相关的变量

#!/bin/sh
#演练while []循环结构
i=1
while((i<=10)) #注意(()前可以不加空格
    do
        echo $i
        let i++;
    done

[liu@WLJY01 myscript]$ sh while_1_2.sh 
1
2
3
...

注意这两种语法的用法,选择好其中一种用法就可以。

3)用while循环实现一个无限循环,每隔3秒钟调用一次程序,在解决队列一类的问题的时候会经常用到。

#!/bin/sh
#演练while [ 1 ] 永久循环结构
while [ 1 ] #数字没有要求,表示为真即可
    do
        echo "the script is running..."
        sleep 3
    done

[liutaostdio@WLJY01 myscript]$ sh while_1_3.sh 
the script is running..
the script is running..
the script is running..

continue 、break 使用

1.循环中有两种类型的控制break和continue
这是一种无条件的流程控制,强制程序跳出当前的循环,或跳出当前循环继续执行下一个循环。

break命令,会退出当前的循环并且将控制权传递到本循环后面的第一个命令

continue命令,当在程序执行过程中遇到这个命令,就会忽略本次循环中剩余的命令,将控制权交给循环的顶部

2.break 程序演示
循环从键盘读入一个字符,输出该字符,当输入的字符为’x’或‘X’时,退出当前循环。

#!/bin/sh
#演练break循环控制流程
while [ 1 ] 
do
    read -p "请输入一个字符:" key
    test $key=x -o $key=X #是x或X
    if [ $? -eq 0]
        then 
            echo "您输入的是x或X,跳出循环..."
        else
            echo $key
    fi
done


[liutaostdio@WLJY01 myscript]$ sh while_break_1.sh 
请输入一个字符:a
请输入一个字符:1
请输入一个字符:x
您输入的是x或X,跳出循环..

3.continue 程序演示
循环从键盘读入一个字符,输出该字符,当输入的字符为’x’或‘X’时,不显示这个字符,进行下一个循环。


#!/bin/sh
#演练continue循环控制流程
while [ 1 ] 
do
    read -p "请输入一个字符:" key
    test $key=x -o $key=X #是x或X
    if [ $? -eq 0]
        then 
            echo "您输入的是x或X,进行下一个循环..."
            continue
            echo "...$key..."  #注意观察这里会不会输出!!!
        else
            echo $key
    fi
done


[liutaostdio@WLJY01 myscript]$ sh  while_continue_1.sh 
请输入一个字符:a
请输入一个字符:b
请输入一个字符:x
您输入的是x或X,进行下一个循环...
请输入一个字符:X
您输入的是x或X,进行下一个循环...

while read 循环使用

1.while read line 可以按行读入
一直到所有行都读完,才退出循环,在实际工作中,会经常采用这种循环结构,进行数据的处理。

语法格式:
cat file.txt |while read line
# line可以换个名字,此处的cat也可以是一个产生若干行的命令,如 find
do
….
done

2.程序演练
循环读入一个文件的所有行,每行按照某种格式输出这行的第一个字段和第二个字段。

#!/bin/sh
#while read line 按行循环读取文件演练
sum_line=0
cat ./ip.txt |while read ipline
    do
        let sum_line++
        echo -n "第$sum_line行..."
        from=`echo $ipline |awk '{print $1}'`  #取每行的第1个字段
        ip=`echo $ipline |awk '{print $2}'`   #取每行的第2个字段
        echo  "$from-------$ip"
        sleep 1
    done
echo "这个文件的行数为:$sum_line"

[liutaostdio@WLJY01 myscript]$ sh while_read_line.sh 
第1行.....上海---------123.124.31.32行.....北京---------175.24.211.83行.....南京---------211.103.156.14行.....广州---------123.124.53.12
这个文件的行数为:0   ???

需要注意的是while read line循环体中的变量退出当前循环后,会被销毁,所以若要二次使用循环体中的变量,则需要采用其他办法。

因为管道后的while loop是sub shell ,所以里面的变量在执行完成后,需要销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值