Linux知识之--函数

简介:

函数

 

systemV风格的服务管理脚本

 

例子

 

给脚本传递一些参数:start, stop, restart, status

myservice.sh

#!/bin/bash

#

lockfile="/var/lock/subsys/$(basename$0)"

case $1 in

    start)

        if[ -f $lockfile ] ; then

            echo"服务已经启动...."

        else

            touch$lockfile

            echo"服务正在启动...."

        fi

        ;;

    stop)

        if[ -f $lockfile ] ; then

            rm-f $lockfile

            echo"服务已经停止...."

        else

            echo"服务尚未启动..."

        fi

        ;;

    restart)

        if[ -f $lockfile ] ; then

            rm-f $lockfile

            echo"服务已经停止...."

        else

            echo"服务尚未启动..."

        fi

        if[ -f $lockfile ] ; then

            echo"服务已经启动...."

        else

            touch$lockfile

            echo"服务正在启动...."

        fi

        ;;

    status)

        if[ -f $lockfile ] ; then

            echo"服务已经启动...."

        else

            echo"服务已经停止...."

        fi

        ;;

    *)

        echo"Usage: $(basename $0) start|stop|restart|status"

        exit5

        ;;

esac

 

 

  把那些在脚本中重复出现并且没有任何改变的代码,封装起来,在适当的场景下调用执行

  程序员将这种被封装起来的代码称为功能体,或叫模块。

 function--函数

    在shell脚本编程中,函数是由若干条shell命令组成的语句块,通常用于代码重用和模块化封装。

 

  函数里面的内容和shell程序形式上是一致的,不同之处,shell代码可以直接被执行,而函数中的内容,不能直独立执行,只有被调用的时候才运行。

 

  函数是在shell程序的当前shell中运行的

 

  定义函数:

    函数是由两部分组成的,一部分是函数名,一部分是函数体(能够实现独立功能的shell语句块)

    语法1

     function func_name{

       函数体

     }

 

    语法2

     func_name(){

       函数体

     }

 

    注意:函数名和()之间不能加空白字符。

  注意:函数可以在交互式环境下定义,也可以在脚本中定义。

 

  函数的使用:

    函数在定义的时候,其函数体中包含的所有命令均不会被执行。只有函数被调用的时候才会执行其中的命令语句。

  调用方式:

    通过直接给出函数名称的方式调用

 

  有很多的函数是存放于专门用于保存函数的文件中。如果想要调用这样的文件中保存的函数,使用source命令(.)加载文件,然后再以直接给出函数名称的方式调用函数。

 

  使用set命令可以查看当前shell中生效的函数。使用unset命令可以撤销已经定义的函数。

 

  函数的返回值:

    两种返回值:

     函数执行结果的返回值

       1.在函数体中使用了echo或printf命令输出的结果

       2.在函数体中的某些命令输出的结果

     函数的状态返回值

       1.函数中最后一条命令的执行状态返回值

       2.自定义退出状态码

         return [n]

          n:0-255 (1 2 127尽可能不用)

          0 表示无错误返回

          1-255 有错误返回

     注意:只要函数在执行时,遇到return命令,不管函数中的命令语句是否全部执行完成,立刻退出函数。

    

  函数的生命周期:

    从被调用的那一刻开始,到遇到return命令或者全部的语句执行完成为止。

 

  函数的实参

    在函数体中,可以使用$1,$2...位置变量为函数提供参数,还可以使用$*或者$@的方式引用所有位置参数,还可以使用$#计算为函数传递的参数的个数。

 

    在调用函数的时候,直接在函数名称后面以空白字符分隔多个参数即可,比如:fuc_name arg1 arg2...

 

    传递给函数参数的位置参数是调用函数的时候,函数名称后面的以空白字符分隔的字符串的序列,跟脚本的位置参数不是一回事。

 

  变量:

   shell中的变量为弱变量

     1.无需事先声明

     2.无需指定变量类型,默认为字符型

 

    变量分类:

     环境变量

       当前shell和子shell

     本地变量

       当前shell

     局部变量

       当前函数体

       local VAR_NAME=VALUE

     位置变量

     特殊变量

 

   建议:手动撤销自己定义或声明的所有变量

 

   函数的递归调用:

     简单来说,就是在函数体中调用函数自身

 

 

 

    阶乘:

        N!=N*(N-1)!=N*(N-1)*(N-2)!=...=N*(N-1)*(N-2)*...*2*1

    shell代码:

#!/bin/bash

# Author: Tianyu.Zhao

#

fact(){

  if[ $1 -eq 0 ] || [ $1 -eq 1 ] ; then

   echo 1

 else

   echo "$[$1*$(fact $[$1-1])]"

  fi

}

 

echo -n "$1!="

fact $1

 

 

    斐波那契数列(黄金分隔数列):

            11 2 3 5 8 13 21 34 55 ...

        假设兔子出生一个月之后才会有繁殖能力:

            N=N-1+ N-2

 

        shell代码:

#!/bin/bash

# Author: Tianyu.Zhao

#

fabonacci(){

  if[ $1 -eq 1 ] ; then

   echo 1

 elif [ $1 -eq 2 ] ; then

   echo 1

 else

   echo $[$(fabonacci $[$1-1])+$(fabonacci $[$1-2])]

  fi

}

#列出所有的斐波那契数列的项

for I in `seq 0 $1` ; do

 fabonacci $I

done

 

 

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

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

#!/bin/bash

# Author: Tianyu.Zhao

#

step=0

move(){

let step++

echo "$step:  move disk $1 $2 -----> $3"

}

hanoi(){

if [ $1 -eq 1 ];then

move $1 $2 $4

else

hanoi "$[$1-1]" $2 $4 $3

move $1 $2 $4

hanoi "$[$1-1]" $3 $2 $4

fi

}

 

hanoi $1 A B C

 

文件abc.txt的内容如下:

2,3,4,5,6

B,c,d,e,f

6,7,8,9,10

f,g,h,i,j

写一个脚本,利用任一循环结构,输出每一行的第二个和第四个字符(以逗号分隔)

 

 

练习:

    写一个脚本:

        1.允许用户通过命令行传递参数,实现用户账户的管理;

        2.如果给出-a|--add选项,就创建该选项后面的用户账户;

        3.如果给出-d|--del选项,就删除该选项后面的用户账户;

        4.如果用户给出-v|--verbose选项,就显示删除或创建用户的信息;

        5.如果用户给出-h|--help选项,就显示帮助信息,并且以0作为退出状态码退出脚本的运行;

        6.如果用户给出其他选项,显示帮助信息,并以5作为退出状态码鬼畜脚本的运行;

 

#!/bin/bash

#Author: Link

#Description: administrate users

#5: no enough args

#6: error args

#

DEBUG=0

ADDUSER=0

DEUSER=0

 

usage(){

    echo"Usage: $(basename $0) -a|--add user1,user2,... | -d|--del user1,user2,...| [-v|-verbose] | [-h|--help]"

    echo

 echo "Options: "

 echo -e "  -a, --add\vCreateuser from list."

 echo -e "  -d, --del\vDeleteuser from list."

 echo -e "  -v,--verbose\vDisplay infomation for your operating."

 echo -e "  -h,--help\vDisplay this menu."

}

 

createuser() {

    ADDUSER_LIST=$(echo$1 | tr ',' ' ')

    forI in $ADDUSER_LIST ; do

        ifid $I &> /dev/null ; then

            [$DEBUG -eq 1 ] && echo "$I exists."

        else

            useradd$I &> /dev/null

            echo$I | passwd --stdin $I &> /dev/null

            [$DEBUG -eq 1 ] && echo "Create $I successfully."

        fi

    done

}

 

deleteuser() {

    DELUSER_LIST=$(echo$1 | tr ',' ' ')

    forJ in $DELUSER_LIST ; do

        ifid $J &> /dev/null ; then

            userdel-r $J &> /dev/null

            [$DEBUG -eq 1 ] && echo "Delete $J finished."

        else

            [$DEBUG -eq 1 ] && echo "$I not exists."

        fi

    done

}

 

if [ $# -le 0 ] ; then

    usage

    exit5

fi

 

while [ $# -ne 0 ] ; do

    case$1 in

        -h|--help)

            usage

            exit

            ;;

        -v|--verbose)

            DEBUG=1

            shift

            ;;

        -a|--add)

            ADDUSER=1

            ALIST=$2

            shift2

            ;;

        -d|--del)

            DELUSER=1

            DLIST=$2

            shift2

            ;;

        *)

            usage

            exit6

            ;;

    esac

done

 

if [ $ADDUSER -eq 1 ] ; then

    createuser$ALIST

fi

 

if [ $DELUSER -eq 1 ] ; then

    deleteuser$DLIST

fi

 

总结:

写一个脚本的步骤:

    1.构建程序主体

        默认是顺序执行结构

        根据需求添加相应的选择结构和循环结构

    2.确定完成某功能所需的命令

    3.调试(bash -x/PATH/TO/SCRIPT_FILE)

    4.写明帮助信息




本文转自 Runs_ 51CTO博客,原文链接:http://blog.51cto.com/12667170/1919265,如需转载请自行联系原作者

相关文章
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
95 6
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
140 3
|
2月前
|
Linux
在Linux内核中根据函数指针输出函数名称
在Linux内核中根据函数指针输出函数名称
|
3月前
|
Linux PHP
Linux CentOS 宝塔 Suhosin禁用php5.6版本eval函数详细图文教程
【8月更文挑战第27天】本文介绍两种禁用PHP执行的方法:使用`PHP_diseval_extension`禁用和通过`suhosin`禁用。由于`suhosin`不支持PHP8,仅适用于PHP7及以下版本,若服务器安装了PHP5.6,则需对应安装`suhosin-0.9.38`版本。文章提供了详细的安装步骤,并强调了宝塔环境下与普通环境下的PHP路径差异。安装完成后,在`php.ini`中添加`suhosin.so`扩展并设置`executor.disable_eval = on`以禁用执行功能。最后通过测试代码验证是否成功禁用,并重启`php-fpm`服务生效。
49 2
|
3月前
|
Shell Linux C语言
Linux0.11 execve函数(六)
Linux0.11 execve函数(六)
67 1
|
3月前
|
Linux API
Linux源码阅读笔记07-进程管理4大常用API函数
Linux源码阅读笔记07-进程管理4大常用API函数
|
3月前
|
安全 Unix Linux
Linux Clone函数
Linux Clone函数
60 3
|
3月前
|
Linux
Linux0.11 文件打开open函数(五)
Linux0.11 文件打开open函数(五)
47 0
|
3月前
|
存储 Linux 调度
Linux 0.11 fork 函数(二)
Linux 0.11 fork 函数(二)
41 0
|
3月前
|
Shell Linux 程序员
在Linux中, 什么是shell函数?如何使用它们?
在Linux中, 什么是shell函数?如何使用它们?