shell编程(十六)函数

一   函数

①  函数的作用

1)就是把程序'多次调用相同的代码'部分定义为一份,然后给这个代码'起个名字'

2)其它所有的'重复调用'这部分代码就'只调用'这个名字即可

3)当需要'修改'这部分代码的时候,只需要'改变函数体内'的一部分代码即可实现所有调用的修改

②  函数的优势

1)把'相同的程序'定义为函数,可以'减少'整个代码的'代码量'

2)可以让程序'代码结构'更清晰

3)增加程序的'可读性',便于管理

4)可以实现'程序功能模块化',不同的程序使用函数模块化

强调:对于shell来说,linux系统的'2000多个命令'可以说是shell的函数

小结:重复调用、思路清晰、'解耦'、修改方便

③  函数的语法

[ function ] name () compound-cmd [redirection]

1)简单语法格式

+++++++++'推荐的方式'+++++++++

    function_name ()
    {
        statement1 # 指令
        statement2
        ....
        statementn
        return n
    }

2)规范语法格式

    function function_name()
    {
       statement1  # 指令
       statement2
       ....
       statementn
       return n
    }

④    函数的执行

1)无参

直接'执行函'数名 --> function_name

注意1:'执行'函数的时候,函数的'小括号()不要带'

注意2:函数'定义'以及函数体必须在'函数执行前定义',函数是'自上而下'执行的!

2)带参数的执行方法

 '函数名'   参数1   参数2 ....

对比:函数的传参和'脚本传参'类似,只是'脚本'换成'函数名'即可!

3)函数后接的参数的说明

1)shell的位置参数($1、$2、$3、$4、$5、$#、$*、$?、$@)都可以是函数的参数

2)此时父脚本的参数'临时'地被函数参数所'掩盖'或隐藏

3)'$0'比较特殊,它仍然是'父脚本的名称'

4)当函数完成时,'原来'的命令行脚本的参数即'恢复'

5)在shell函数里面,'return命令'功能与shell里的exit类似,作用是'跳出函数'

6)在shell函数体里'使用exit'会退出整个'shell脚本',脚本直接'game over'

7)return语句会'返回一个退出值(返回值)'给调用函数的程序

8)函数的参数变量是在函数体里面定义,如果是'局部变量-->函数外不能调用',一般使用'local'定义

二  shell函数实践

①  无参调用函数

②  有参调用函数

在shell中,函数可以被'当作命令'一样执行,它是命令的'组合结构体'

③  local

备注: 函数中'推荐'使用'local'

④  脚本A调用脚本B函数

1)自己写的一些'函数放到脚本'中,并将这些脚本放到'目录'中,然后将该目录'加入'到PATH路径

2)source 加载脚本-->'不需要前缀'

场景: 创建公共的'函数的库文件',然后可以在'不同脚本中引用'该库文件

1)脚本B

2)脚本A

开源函数库

安装博客

3)执行

⑤  优先级

'(function)函数' > '(alias)别名' > '命令(cmd)自身'

⑥  继承

1)变量是会被'子进程继承'的,可以'直接'使用

2)有些情况下可能需要'继承函数',以方便'透明使用' --> 使用"export -f",'不带参数'的export只针对'变量'

1)不用export -f声明 

2)使用export -f声明

⑦  return

shell获取函数的返回值

1)shell 函数返回值只能是'整形数值' --> 否则报错"numeric argument required"

2)一般是用来表示函数'执行成功与否'的,'0'表示'成功',其他值'表示失败'

3)不带'return'关键字,也即'默认行为' --> 会返回'函数体'中'最后一个命令'的返回值

4)让函数返回一个或多个值,可以'定义全局变量',函数将计算结果'赋给全局变量',然后脚本中其他地方通过'访问全局变量',就可以获得那个函数"返回"的一个或多个执行结果了

1)默认行为

不定义'return'  -->执行成功默认是'0'

shell的函数'默认'是返回0和1来表示'是否成功'的

2)return返回值只能是整数

通过return只能'返回整数值',并且是'[0-255]'的范围,超过则'截断'

3)将函数return结果保存下来

获取shell函数的执行结果

函数返回值和echo的关系

``和$()的区别

4)其它方式保存结果

1)在'函数外'定义一个'全局'变量,然后在函数中'赋值'这个变量

2)这样'调用函数'后,全局变量就变了,达到'同样的效果'

#!/bin/sh
num=10
add(){
     echo "hello"
     ((num++))
}

⑧  递归

1) '结束条件'

2) '递归体'

+++++++++'计算阶乘'+++++++++

#!/bin/bash
function factorial {
   if [ $1 -eq 1 ]
   then
     # 结束条件
     echo 1
   else
     local temp=$[ $1 - 1 ]
     # 递归调用
     local result=$(factorial $temp)
     echo $[ $result*$1 ]
   fi
}

⑨  递归调用问题

function ls() { ls -l; }  -->  '无限递归'

⑩  小结

/etc/init.d/functions

三  实践

①  需求1:函数传参转成脚本命令传参,对任意指定的URL判断是否异常

思路

1)'脚本传参'检查web url是否正常

2)检查的功能'写成函数'

3)函数传参转成'脚本命令传参',对任意的URL判断是否异常

1)命令行参数测试

curl -I -m 3 -o /dev/null -s -w %{http_code} www.baidu.com

curl命令

-I 仅'测试HTTP头'

-m 3 最多'查询3秒'

-o /dev/null '屏蔽'原有输出信息

-s silent 模式,'不输出任何东西'

-w %{http_code} 控制'额外'输出 

2)函数的形式

#!/bin/bash
# 有系统函数库就加载进来-->用其颜色
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
# 定义用法--->用户错误提示
usage(){
        echo "USAGE:$0 url"
        exit 1
}
# 定义函数-->明白wget相关参数的含义
Check_Url(){
        wget -T 10 --spider -t 2 $1 &>/dev/null
        # 定义变量-->初始化
        RETVAL=$?
        if [ $RETVAL -eq 0 ]
        then
                action "$1 url " /bin/true
        else
                action "$1 url " /bin/false
        fi
        return  $RETVAL
}
# 主函数
main(){
        # 判断参数的个数
        if [ $# -ne 1 ];then
                # 用户输入错误的提示
                usage
        fi
        Check_Url $1
        RETVAL=$?
        return  $RETVAL
}
# 真正开始调用函函(习惯用$*)-->传递的脚本的所有参数为整体作为函数的$1
main $*

#############测试##################

# sh function3.sh baidu.com

wget常用的命令

-T                              # 将所有超时设为SECONDS 秒

--spider                        # 不下载任何文件,测试url的有效性

-t                              # 置重试次数为 NUMBER (0 代表无限制),可能由于网络的原因

-d                              # 打入后台(daemon)

-c,   --continue                # 断点续传下载文件
      --progress=TYPE           # 选择进度条类型(dot 和 bar两种),后者是默认的
                                # wget通常将它的输出记录到下载目录中的wget-log 文件

-O,  --output-document=FILE     # 将文档写入 FILE

wget的其它实践

也很不错的教程

更细化的

  练习2:给字符串加颜色

需求:传递两个参数,第一个参数是'颜色',第二个参数是'内容',为'不同的内容'显示不同的颜色

1)规范的脚本形式

#!/bin/bash
#(1)定义颜色
RED_COLOR='\e[1;31m'
GREEN_COLOR='\e[1;32m'
YELLOW_COLOR='\e[1;33m'
BLUE_COLOR='\e[1;34m'
PINK='\e[1;35m'
# 关闭颜色
RES='\e[0m'
#(2)健壮性-->判断函数的个数
usage(){
	echo "USAGE:$0 {red|green|yellow|pink}" contents
	exit 1
}
#(2)使用颜色-->标准是case-->注意空格的问题,用{}解决
color(){
if   [ "$1" = "red" ];then
	echo -e "${RED_COLOR}$2 $RES"
elif [ "$1" = "pink" ];then
	echo -e "${PINK}$2 $RES"
elif [ "$1" = "green" ];then
	echo -e "${GREEN_COLOR}$2 $RES"
elif [ "$1" = "yellow" ];then
	echo -e "${YELLOW_COLOR}$2 $RES"	
else
	usage
fi
}
main(){
	if [ $# -ne 2 ];then
		usage
	fi
	color $1 $2
}
# 函数调用
main $*
# 多行注释的方式
:<<EOF
echo -e "$RED_COLOR red $RES"
echo -e "$GREEN_COLOR GREEN $RES"
echo -e "$YELLOW_COLOR YELLOW $RES"
echo -e "$BLUE_COLOR BLUE $RES"
echo -e "$PINK PINK $RES" 
EOF

2)扩展

vim /etc/DIR_COLORS

 82 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
 83 # Background color codes:
 84 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值