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

本文介绍了Shell编程中的双重循环,详细讲解了如何使用九九乘法表,并探讨了until语句的结构和应用。同时,深入讨论了Shell函数,包括其定义、调用方法、应用实例以及参数和作用范围,还提到了递归函数的概念。

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

一:使用九九乘法表

mark

[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

mark

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` <username> [<message>]"
  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函数定义

mark

  • 其中,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下的所有文件列出来

    mark

[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
........
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值