shell编程之函数

函数:函数function是由若干条shell命令组成的语句块,实现代码 重用和模块化编程
 
 
    1)函数的定义: 可在 命令行,脚本的一部分,只有函数的单独文件 中定义
        两部分组成:函数名和函数体;函数体可带有返回状态值 return #
         -语法一:
            function f_name {
            …函数体…
            }
 
         -语法二:
            f_name() {
            …函数体…
            }
 命令行下定义并调用函数

]#dir (){ ls;}
]#dir

 
    2)函数的调用: 函数只有被调用时才会执行
        给定函数名:
            无参数调用 f_name
            有参数调用 f_name arg1 arg2 …
  
        函数被调用时创建,返回时终止。
  
     命令行下: 定义函数后可直接调用  使用 #unset f_name 撤销函数
 
     脚本中: 函数定义后才可使用,应将函数放在脚本开始部分
 
     函数文件: 将常用函数写入函数文件,在命令行或脚本中加载该函数文件即可调用函数
        #set 查看所有已加载函数  #unset 删除函数
 
      加载函数:
       source /path/to/filename
       . /path/to/filename
 
   加载函数文件

]#vi echo.sh
#!/bin/bash
#zjj
print_haha (){
 echo haha
 }
]#source echo.sh
]#print_haha
]#haha


    3)函数参数
        传递参数给函数:
        f_name arg1 arg2..
   
    函数体可使用$1,$2,…调用对应参数;$@,$*,$#等同样可用

    注意 此处的的$1.$2与执行脚本时的参数不同,仅为调用函数时后面添加的参数


    4)函数变量
    注意 函数体中变量的操作会影响到整个脚本,
        可在函数中定义局部变量,只对函数体有效,使用local
        local var_name=value
  
    5)函数的递归
        函数直接或间接调用自身
        注意递归层数
  
 


===  函数练习:
 
 1.写一个服务脚本/root/bin/testsrv.sh

#!/bin/bash
#zjj
testsrv() {

    bsname=`basename $0`
    local Srvpath=/var/lock/subsys/$bsname
    
    case $1 in
    start)        
        if [ -e $Srvpath ] ;then            
            echo +  $bsname is running        
        else            
            touch $Srvpath && echo ++ start successful          
        fi        
        ;;    
    stop)        
        if [ -e $Srvpath ] ;then            
            rm -f $Srvpath &&echo -- stop successful        
        else            
            echo -  $bsname is dead        
        fi        
        ;;    
    restart)        
        testsrv stop && testsrv start        
        ;;    
    status)        
        [ -e $Srvpath ] &&echo +  $bsname is running...  ||echo -  $bsname is stopped...        
        ;;    
    *)        
        testsrv status        
        ;;    
    esac
        
        }
testsrv $1



 2.编写一个脚本/root/bin/copycmd.sh ,复制命令及其库文件

#!/bin/bash
#zjj
copycmd() {

# create directiry if they does not exist
    local dpath='/testdir/sysroot'
    for dir in `echo $PATH|tr ':' ' '` "/lib" "/lib64" ;do
    [ -e ${dpath}${dir} ] &&continue ||mkdir -p ${dpath}${dir}
    done
    
while true ;do
    read -p "++enter a command or [quit]:" cmd
    [[ $cmd =~ quit ]] &&exit 23
    spath=`whereis -b $cmd 2>/dev/null|cut -d ' ' -f2`
    ! [ $? -eq 0 ] && echo invalid command &&continue
    cp -a $spath ${dpath}$spath &&echo copy  $spath ++succesful ||echo --error
    
    for so in `ldd $spath |sed -nr 's/.*> ([^[:space:]].*) \(.*/\1/p'`;do
        cp -n $so ${dpath}$so &&echo -e "copy  $so   \t++successful" ||echo --error
    done
done
}
copycmd

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

#!/bin/bash
#zjj

max (){
[ $1 -gt $2 ]&&echo max:$1||echo max:$2
}
max $1 $2


 4.斐波那契数列

#!/bin/bash
#zjj

fibo() {
    if [ $1 -le 1 ];then
        echo $1    
    elif [ $1 -gt 1 ];then
        echo "$[$(fibo $[$1-1])+$(fibo $[$1-2])]"
    fi
}

if ! [ $1 -eq $1 ]&>/dev/null||[ $1 -lt 0 ]&>/dev/null||[ -z $1 ] ;then
    echo please enter a integer &&exit 23
else
    for((i=0;i<=$1;i++));do
        fibo $i
    done
fi

 
 
 5.汉诺塔解决

#!/bin/bash
#zjj

# move n-1 : A to B
# move n   : A to C
# move n-1 : B to C

hanoi() {
    if [ $1 -eq 1 ];then
        echo $2 to $4
    else
        hanoi $[$1-1] $2 $4 $3
        echo $2 to $4
        hanoi $[$1-1] $3 $2 $4
    fi
}
hanoi $1 A B C


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

(0)
JasperJasper
上一篇 2016-08-21 20:46
下一篇 2016-08-21 20:46

相关推荐

  • class14磁盘管理(一)

    一、硬盘基础知识及分区类型 1、磁盘结构 设备文件 I/O Ports: I/O 设备地址 一切皆文件:   open(), read(), write(), close() 设备类型: 块设备:block,存取单位“块”,磁盘 字符设备:char,存取单位“字符”,键…

    Linux干货 2016-08-29
  • linux文本处理三剑客—grep

      cat:concatenate 文本文件查看工具 cat [option] filename… -n:给显示出来的文本行加上编号 -b:非空行编号 -V:显示 ^ -E:显示行结束符$ -T:显示制表符 -A:显示所有控制符-A=-VET -s:压缩连续…

    系统运维 2016-08-05
  • 磁盘及文件系统管理应用实例

    磁盘及文件系统管理应用实例 1.创建一个10G的分区,并格式化为ext4文件系统 要求其block大小为2048,预留空间百分比为2,卷标为MYDATA,默认挂载属性包含acl 挂载至/data/mydata目录,要求挂载时禁止程序自动运行,且不更新文件的访问时间戳 [root@master ~]# fdisk /dev/sdb Command (m for…

    Linux干货 2017-08-14
  • M22 Centos设置yum源方法

    实验目的: 使用虚拟机模拟建立yum源服务器,在客户机上指定yum源为该服务器。 实验器材: WMware12安装Centos6.8虚拟机作为yum服务源 WMware12安装Centos7.3 作为客户端访问yum源服务器 实验原理图: 实验过程: 服务器端: 1、  显示已经挂载的光盘 #cd /misc/cd #先执行此命令才可以看到光盘挂载…

    2017-03-06
  • 如何将迁移home到独立分区中

        背景(centos7中):         由于在刚开始学习linux时磁盘分配追求简单,只是把一个磁盘简单的分了3个分区。现在,因用户数据增多、磁盘空间变少、当数据撑满磁盘时,会导致系统崩溃。为防止此种情况的发生我必须把把根下的/home 目录迁移出 来独立分…

    2017-08-10
  • Linux中的cut、sort、uniq以及用户(组)管理类指令应用示例

    Linux中的cut、sort、uniq指令 列出当前系统上所有已经登录的用户的用户名,注意:同一用户登录多次,只显示一次。 解决思路: 先使用who指令显示出所有已登录的用户。然后对who指令的输出进行切割得到想要的第一列内容,即只包含用户名。可以使用cut指令。最后对cut的结果进行排序并去重。可以使用sort指令。   借助管道符,可以方便的…

    Linux干货 2016-11-13