Shell脚本编程—特殊用法(select)及函数、递归

Shell脚本编程—特殊用法及函数

 

一、while的特殊用法:

1、使用格式:

while read 变量名;do

   循环体

done </PATH/TO/filename

注:依次从指定的文件中的内容逐行读取,并把读取到的每行赋值给变量。

2、例题:

扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为13800138000,并提示该用户的GECOS信息修改成功。

如下图,修改前:

blob.png

如下图,修改后及代码:(如果不需要操作过程的信息,可在代码行“chfn后面添加/dev/null”)

脚本代码:

blob.png

blob.png 

二、双小括号的使用(类似C语言的编写风格):

1、双小括号方法,可以使bash Shell实现C语言风格的变量操作;也可以用于算术运算,(())格式,

#I=10

#((I++))

for循环的特殊格式:

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式));do

循环体

done

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

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

2、例题:做九九乘法

  脚本代码:

 blob.png

  代码及效果图:

 blob.png

三、select菜单的特殊使用:

1、使用格式:

selec t  variable  in  list ;do

循环体命令

done

2select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入;用户输入菜单列表中的某个数字,执行相应的命令;用户输入被保存在内置变量REPLY 中。

3selectcase的结合使用:

select 是个无限循环,因此要记住用break 命令退出循环,或用exit 命令终止脚本。也可以按ctrl+c 退出循环。

 select 经常和case 联合使用

 for 循环类似,可以省略in list ,此时使用位置参量($*$@……)

4、例题:做一个脚本文件初始创建的模板

  如下,为脚本代码、执行步骤及效果图:

 blob.png

四、函数:

1、函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程。

2、函数与shell的对比:

它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分。

3、函数和shell程序比较相似,区别在于:

   Shell程序在子Shell中运行

  Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改

4、认识函数的使用格式:函数由两部分组成:函数名和函数体。

  语法一:

function f_name{

函数体

}

  语法二:

function f_name(){

函数体

}

  语法三:

f_name(){

函数体

}

5、函数的定义和使用:

可在交互式环境下定义函数

可将函数放在脚本文件中作为它的一部分

可放在只包含函数的单独文件中

  调用:函数只有被调用才会执行;

调用:给定函数名

函数名出现的地方,会被自动替换为函数代码

 函数的生命周期:被调用时创建,返回时终止

6、简单认识函数:如下图

定义该函数add后,若在#后面键入add,其显示结果同ls-l的作用相同。删除定义的函数命令是:#unset add

 blob.png

 blob.png

注意:脚本内的$1$2变量与函数add内的$1$2是不一样的,要区分开来。

7、脚本内的函数调用:

函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它后才能使用

  调用函数仅使用其函数名即可。

   如下图:

   blob.png

  注意,下图中的变量不能够放在函数的前面,否则函数无法使用和调用赋值计算:

 blob.png

8、写一个专门存放函数的文本,提供给其他的程序调用:

  A、可以将经常使用的函数存入函数文件,然后将函数文件载入shell;件名可任意选取,但最好与相关任务有某种联系。例如:functions.main

  B、一旦函数文件载入shell,就可以在命令行或脚本中调用函数。可以使用set命令查看所有定义的函数,其输出列表包括已经载入shell的所有函数。

 blob.png

C、若要改动函数,首先用unset命令从shell中删除函数。改动完毕后,再重新载入此文件。

D、调用函数文本格式:函数文件已创建好后,要将它载入shell

  定位函数文件并载入shell的格式:

. filename source filename

  注意:此即<> <空格> <文件名;这里的文件名要带正确路径

 

  事例:

  方法一:

  blob.png

  方法二:

  blob.png

  方法三:shell进程里面的子shell调用同一个函数:

  blob.png

(注:函数可以接受参数,调用函数时,在函数名后面以空白分隔给定参数列表即可;例如“testfuncarg1 arg2 …”;在函数体中当中,可使用$1, $2, …调用这些参数;还可以使用$@, $*, $#等特殊变量)

9、函数的变量:

  A、变量作用域:

环境变量:当前shell和子shell有效

本地变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数。

局部变量:函数的生命周期;函数结束时变量被自动销毁

    注意:如果函数中有局部变量,如果其名称同本地变量,使用局部变量。

  B、在函数中定义局部变量的方法:local NAME=VALUE

    事例:局部变量的定义

    变量定义前:如下图,shell脚本里面的变量与函数里面的变量名同名的情况下,shell脚本的变量无效。

   blob.png

    变量定义后:

  blob.png

10、函数的两种返回值:

  A、函数的执行结果返回值:

  (1) 使用echoprintf命令进行输出

  (2) 函数体中调用命令的输出结果

  B、函数的退出状态码:(一般用于条件判断时,当满足条件时,结束函数进程)请见例题2

  (1) 默认取决于函数中执行的最后一条命令的退出状态码

  (2) 自定义退出状态码,其格式为:

     return 从函数中返回,用最后状态命令决定返回值

     return 0 无错误返回。

     return 1-255 有错误返回

 

  例题:

  1、写一个函数实现两个数字做为参数,返回最大值

  blob.png

 2、写一个函数实现数字的加减乘除运算,例如输入1 + 2,,将得出正确结果

 blob.png

(如下图,需求不同,代码也不一样)

11、函数的递归:

  1、函数递归:函数直接或间接调用自身;但需要注意递归层数。

  2、递归实例:

    阶乘是基斯顿·卡曼于1808 年发明的运算符号,是数学术语

    一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1。自然数n的阶乘写作n!

    n!=1×2×3××n

    阶乘亦可以递归方式定义:0!=1n!=(n-1)!×n

    n!=n(n-1)(n-2)…1

    n(n-1)! = n(n-1)(n-2)!

3、示例:digui.sh

 blob.png

事例:

1、斐波那契数列又称黄金分割数列,因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0112358132134、……,斐波纳契数列以如下被以递归的方法定义:F0=0F1=1Fn=F(n-1)+F(n-2)n2

写一个函数,求n阶斐波那契数列

代码和效果如下图:

从题目中可以得知,从2开始,后一个数值是前两个数值的之和;因此,$11时,值为1$12时,为0+1=1$13时,为1+1=1……

blob.png

2、汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

利用函数,实现N片盘的汉诺塔的移动步骤

代码和效果如下图:

三根柱子分别为:ABC

如果没有圆盘,则输出为空;

如果只有一个圆盘,则可以直接从柱子A移动到移动C,所以echo $2—$4

如果有两个及以上的圆盘,第一步先要借助柱子Cn-1的圆盘移动到柱子B上,因此第一个递归ta $(($1-1)) $2 $4 $3ACB),所以是echo $2—-$4(第n个圆盘的移动);第二步是将第一步移动到柱子B上存放的n-1圆盘借助柱子A来调换到柱子C上,即是第二个递归ta $(($1-1)) $3 $2 $4,因此,所以是echo $2—-$4

blob.png

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

(2)
Aaron_wangAaron_wang
上一篇 2016-08-21
下一篇 2016-08-21

相关推荐

  • LINUX-echo命令

    echo命令:回显         语法:echo [-neE][字符串]     说明:echo会将输入的字符串送往标准输出。输出的字符串间         以空白字符隔开,并在最后加上换行号。   &nbs…

    Linux干货 2017-05-22
  • Nginx的简单配置和简单实验..

    yum install nginx #安装Nginx,安装包在epel源中 systemctl start nginx.service #启动服务 #实验:配置一个虚拟主机 #先给一个网页文件 ~]#mkdir /data/nginx/vhost1 -pv ~]#vim /data/nginx/vhost1/index.html <h1>Ngin…

    Linux干货 2017-06-19
  • N25-第12周博客作业

    1、请描述一次完整的http请求处理过程;   1)客户端和服务器端建立连接。服务器接收或者拒绝请求。   2)服务器端接收客户端请求。接收来自于网络的请求报文中对某资源的一次请求。对请求的处理响应,可分为单进程(启动一个进程处理请求,一次只处理一个)和多进程(并行启动多个进程,每个进程处理一个请求)。  &…

    Linux干货 2017-05-21
  • Linux下的SSH端口转发

    通常情况下两个不同的网络之间总会开放某一些特定的端口用于通讯使用,而SSH所使用的22端口通常就在开放之列。基于SSH的端口转发就是利用SSH作为中间的代理,达到绕过两个网络之间的限制,顺利的进行任意的端口的访问。端口转发可以分为三种,正向端口转发,反向端口转发和动态端口转发。为了演示这三种端口转发方式的用法我们先假设存在有2个网域Office和Prod,在…

    Linux干货 2015-02-09
  • 马哥教育网络班20期-第四周课程作业

    Table of Contents 1、复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。 2、编辑/etc/group文件,添加组hadoop。 3、手动编辑/etc/passwd文件新增一行,添加用户hadoop,其基本组ID为hadoop组的id号;其家目录为/home/h…

    Linux干货 2016-06-26
  • Mozart的剑(文本处理工具)——叁剑(grep、正则表达式)

    之前的句子 烟锁池塘柳 炮镇海城楼 因荷而得藕 有杏不需梅 认识于小林寒风的一篇小说《凤山遗梦》 grep grep是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。 作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行。模式:由正则表达式字符及文本字符所编写的过滤条件 用法: grep [OPTIO…

    2017-08-03

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-21 21:14

    文章条理结构清晰,层次分明,图文并貌,需要注意的地方是,图片不够清晰。