Shell编程----双重循环与函数

Shell编程----双重循环;until语句;函数

文章目录

  • Shell编程----双重循环;until语句;函数
  • 一:使用九九乘法表
  • 二:使用九九乘法表
  • 三:until语句
    • 3.1:until语句的结构
    • 3.2:until语句应用1
    • 3.3:until语句应用2
  • 四:shell函数
      • 4.1:shell函数概述
      • 4.2:shell函数定义
      • 4.3:调用函数的方法
      • 4.4:shell函数应用1
      • 3.5:shell函数应用2
      • 3.6:shell函数的作用范围
      • 3.7:shell函数的参数
      • 3.8:shell函数的递归

一:使用九九乘法表

Shell编程----双重循环与函数_第1张图片

[root@shell shell]# cat jiujiu.sh
#!/bin/bash
for ((i=1;i<=9;i++))
do
  for ((j=1;j<=i;j++))
  do
     echo -ne "${i}x${j}=$[$i*$j]\t"
  done
  echo""
done
sh
[root@shell shell]# sh jiujiu.sh 
1x1=1	
2x1=2	2x2=4	
3x1=3	3x2=6	3x3=9	
4x1=4	4x2=8	4x3=12	4x4=16	
5x1=5	5x2=10	5x3=15	5x4=20	5x5=25	
6x1=6	6x2=12	6x3=18	6x4=24	6x5=30	6x6=36	
7x1=7	7x2=14	7x3=21	7x4=28	7x5=35	7x6=42	7x7=49	
8x1=8	8x2=16	8x3=24	8x4=32	8x5=40	8x6=48	8x7=56	8x8=64	
9x1=9	9x2=18	9x3=27	9x4=36	9x5=45	9x6=54	9x7=63	9x8=72	9x9=81	

二:使用九九乘法表

[root@shell shell]# cat sanjiao.sh 
#!/bin/bash
#行
for ((i=1;i<=5;i++))
do
  #倒立直角三角
  for ((j=5;j>=i;j--))
    do
      echo -n " "
    done
  #等腰三角形
  for ((k=1;k<=2*i-1;k++))
    do
      echo -n "*"
    done
    echo ""
done

[root@shell shell]# sh sanjiao.sh 
     *
    ***
   *****
  *******
 *********

[root@shell shell]# vim sanjiao.sh
#!/bin/bash
#行
for ((i=1;i<=5;i++))
do
  #倒立直角三角
  for ((j=5;j>=i;j--))
    do
      echo -n "#"
    done
  #等腰三角形
  for ((k=1;k<=2*i-1;k++))
    do
      echo -n "*"
    done
    echo ""
done
[root@shell shell]# sh sanjiao.sh 
#####*
####***
###*****
##*******
#*********

总结:双层循环,行执行一次,列执行一圈

三:until语句

3.1:until语句的结构

  • 重复测试某个条件,只要条件不成立则反复执行
until 条件测试操作
do
 命令序列
done
while 未超过10
do
 数字依次增加
done

Shell编程----双重循环与函数_第2张图片

3.2:until语句应用1

  • 计算1–50的和

    通过循环累加的方式计算1–50的和

[root@shell shell]# vim sum50.sh
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
do 
  let sum+=$i
  let i++
done
echo "$sum"

[root@shell shell]# sh sum50.sh 
1275

3.3:until语句应用2

  • 为指定用户发送在线消息

    • 若指定用户不在线(未登陆系统),则每10分钟(实验中为了测试效果,可改为3s)试一次,直至用户登录系统后再发送信息

    • 用户名与消息通过为止参数传递给脚本

  • 分析需求

    1.位置参数个数大于1

    2.姓名属于系统用户

    3.用户是否在线

    4.发送消息 echo “消息” | write 用户名

[root@shell shell]# vim mes.sh 

#!/bin/bash
username=$1
#格式参数不能为空
if [ $# -lt 1 ] ;then
  echo "Usage:`basename $0`  []"
  exit 1
fi
#验证是否属于系统用户
if grep "^$username" /etc/passwd > /dev/null;then :
else
  echo "not user"
  exit 2
fi
#测试用户是否在线,如果不在线,每5s联系一次
until who|grep "$username" > /dev/null;do
 echo "user not login"
 sleep 3
done
#发送消息
echo "$2" | write "$username"
echo "${username}发送成功"

[root@shell shell]# sh mes.sh lpf hello
lpf发送成功
[root@shell shell]# vim mes.sh 
[root@shell shell]# sh mes.sh lisi hello
user not login
user not login
^C
[root@shell shell]# sh mes.sh wangwu hello
user not login
user not login
^C
[root@shell shell]# sh mes.sh sass hello
not user

四:shell函数

4.1:shell函数概述

  • shell一个非常重要的特性是它可作为一种编程语言来使用。
  • 因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释。而程序的加载和解释都是非常耗时的。
  • 针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。
  • shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们
  • shell函数将命令序列按格式写在一起
  • 可以方便重复使用命令序列

4.2:shell函数定义

Shell编程----双重循环与函数_第3张图片

  • 其中,return返回的是状态码,需要使用$?调取

  • echo 返回的是值,使用变量调用

  • 传参:指位置变量

  • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

  • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

4.3:调用函数的方法

  • 函数名 [参数1($1)] [参数2($2)]
  • 在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
  • 10不能获取第十个参数,获取第十个参数需要10 不能获取第十个参数,获取第十个参数需要10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数。

4.4:shell函数应用1

  • 两个数字求个

  • 通过sum(){}定义函数

  • 使用read命令交互输入两个数并求和

[root@shell shell]# vim num12.sh 
#!/bin/bash
function sum(){
  read -p "请输入第一个整数: " num1
  read -p "请输入第二个整数: " num2
  SUM=$[$num1+$num2]
  echo $SUM
  return 100
}
number=`sum`
echo $?             '上一条是函数返回值是函数里的返回值'
echo $number 
[root@shell shell]# sh num12.sh 
[root@shell shell]# sh num12.sh 
请输入第一个整数: 10
请输入第二个整数: 20
100
30
[root@shell shell]# vim num12.sh 
#!/bin/bash
function sum(){
  read -p "请输入第一个整数: " num1
  read -p "请输入第二个整数: " num2
  SUM=$[$num1+$num2]
  echo $SUM
  return 100
}
number=`sum`
echo $number 
echo $?             '返回值是上一条命令的状态码'
[root@shell shell]# sh num12.sh 
请输入第一个整数: 10
请输入第二个整数: 20
30
0

3.5:shell函数应用2

  • 编写登录系统后便可使用的自定义函数
    • 编辑用户自定义函数文件/root/function
    • 在当前shell中加载可执行的函数文件/root/function
    • 在~/.bashrc文件中添加source /root/function命令

3.6:shell函数的作用范围

  • 函数在shell脚本中仅在当前Shell环境中有效

  • Shell脚本中变量默认全局有效

  • 将变量限定在函数内部使用local命令

  • 示例

    函数内部变量通过local来实现

    函数内部和外部分别赋值,进行结构验证

#local $score在函数内部则仅限于函数内
[root@shell shell]# vim num12.sh 
#!/bin/bash
function sum(){
  read -p "请输入第一个整数: " num1
  read -p "请输入第二个整数: " num2
  SUM=$[$num1+$num2]
  local score=100
  echo "函数内$sore"
  echo "和: $SUM"
}
sum
echo "函数外$score"

[root@shell shell]# sh num12.sh 
请输入第一个整数: 10
请输入第二个整数: 20
函数内
和: 30
函数外         "local内部变量,外部无法输出"
[root@shell shell]# vim ~/.bashrc
......
#添加
function sum(){
  read -p "请输入第一个整数: " num1
  read -p "请输入第二个整数: " num2
  SUM=$[$num1+$num2]
  echo "和: $SUM"
}
[root@shell shell]# source ~/.bashrc
[root@shell shell]# sum
请输入第一个整数: 10
请输入第二个整数: 20
和: 30

解决方法:把函数里面的返回值再抛出来给外部用

[root@shell shell]# vim num12.sh 

#!/bin/bash
function sum(){
  read -p "请输入第一个整数: " num1
  read -p "请输入第二个整数: " num2
  SUM=$[$num1+$num2]
  local score=100
  echo $score
}
s=`sum`
echo $s

[root@shell shell]# sh num12.sh 
请输入第一个整数: 10
请输入第二个整数: 20
100

3.7:shell函数的参数

  • 参数的表示方法

    函数名称 参数1 参数2 参数3

  • 参数的表示方法

    $1 $2 $3 ........${10} ${11}
    

3.8:shell函数的递归

  • 调用自己本身的函数

  • 示例

    递归遍历目录

    通过定义递归函数lisy_files来实现

  • 语法

    function sum(){
    ......
    s=`sum`               #自己调用自己
    ......
    }
    
  • 示例:把/var/log下的所有文件列出来

    Shell编程----双重循环与函数_第4张图片

[root@shell shell]# vim digui.sh

  for f in `ls $1`
  do
    #判断是否为目录
    if [ -d "$1/$f" ];then
      echo "$2$f"
      #递归调用
      list_files "$1/$f" " $2"   
    else
      echo "$2$f"
    fi
  done
}
list_files "/var/log" ""        #调用list_files函数

[root@shell shell]# bash digui.sh 
anaconda
 anaconda.log
 ifcfg.log
 journal.log
 ks-script-lwtzEm.log
 packaging.log
 program.log
 storage.log
 syslog
 X.log
audit
 audit.log
boot.log
boot.log-20200715
boot.log-20200716
boot.log-20200717
boot.log-20200719
boot.log-20200720
boot.log-20200721
btmp
chrony
cobbler
 anamon
 cobbler.log
 install.log
 kicklog
 syslog
 tasks
  2020-07-19_213002_sync.log
  2020-07-19_213253_sync.log
  2020-07-19_213408_get_loaders.log
  2020-07-19_214234_import.log
  2020-07-19_225654_sync.log
........

你可能感兴趣的:(Shell编程)