版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
一 函数
函数具有类似别名的作用,函数的作用就是把程序多次调用相同的代码部分定义为一份,然后给这个代码起个名字,其它所有的重复调用这部分代码就只调用这个名字即可,当需要修改这部分代码的时候,只需要改变函数体内的一部分代码即可实现所有调用的修改!
二 函数的优势
(1)把相同的程序定义为函数,可以减少整个代码的代码量!
(2)可以让程序代码结构更清晰
(3)增加程序的可读性,便于管理
(4)可以实现程序功能模块化,不同的程序使用函数模块化!
# 强调:对于shell来说,linux系统的2000个命令可以说是shell的函数!
# 重复调用、思路清晰、解耦、修改方便
三 shell函数的语法
(1)简单语法格式
function_name ()
{
statement1 # 指令
statement2
....
statementn
return n
}
(2)规范语法格式
function function_name()
{
statement1 # 指令
statement2
....
statementn
return n
}
细节对比:shell的返回值exit输出返回值,函数里用return 输出返回值
四 函数的执行
(1)无参--->直接执行函数名
注意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脚本,而不是退出shell函数
7、return语句会返回一个退出值(返回值)给调用函数的程序。8、函数的参数变量是在函数体里面定义,如果是普通变量,一般使用local i定义
五 实践
练习1
#!/bin/bash
#(1)定义
wzj(){
echo "I am wzj!"
}
#(2)调用
wzj
# 调用 ---> sh function1.sh
练习2
vim /etc/init.d/functions
# 增加(在最后的return 0)之前
706 jzw(){
707 echo "hello"
708 }
# 直接在脚本中定义和调用函数!
调用
#!/bin/bash
#(1)加载
source /etc/init.d/functions
#(2)调用
jzw
# 在其它脚本中定义函数,然后在本脚本中调用函数!
思考:后续自己定义一些函数,然后在其它shell脚本中引入!
练习3:传递参数
#!/bin/bash
# 函数传递参数
wzj(){
echo "I am $1"
}
# 脚本给函数传参
wzj $1 # sh function2.sh wzj
wzj hello # sh function2.sh
练习4:函数传参转成脚本命令传参,对任意指定的URL判断是否异常
思路
(1)脚本传参检查web url是否正常
(2)检查的功能写成函数
(3)函数传参转成脚本命令传参,对任意的URL判断是否异常
命令行参数的测试
curl -I -m 3 -o /dev/null -s -w %{http_code} www.baidu.com
-I 仅测试HTTP头
-m 3 最多查询3秒
-o /dev/null 屏蔽原有输出信息
-s silent 模式,不输出任何东西
-w %{http_code} 控制额外输出
函数的形式
#!/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
练习5:给字符串加颜色
需求:传递两个参数,第一个参数是颜色,第二个参数是内容,为不同的内容显示不同的颜色
规范的脚本形式
#!/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
核心:思想
关于颜色可以参考我这篇文章
方法:用case或者if完成
扩展
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
对比:``和$()的区别
sh
#(1) 使用“-n”选项进行shell脚本的语法检查,
#(2) 使用“-x”选项实现shell脚本逐条语句的跟踪,巧妙地利用shell的内置变量增强“-x”选项的输出信息等
补充:函数中的变量均为全局变量,没有局部变量
感悟:练习和思维,重要的是让面试官相信你会!
shell学习思路:思路--->编写