bash支持使用函数,函数出现的地方,而自动被替换成函数定义的代码,一个函数定义后可以多次被重复使用,大大减少代码量
函数定义格式:
第一种
FuncName() { 函数体 }
第二种
function FuncName { 函数体}
函数有两种返回值:
正常返回的数据: 函数中的打印语句,如echo或print 函数中命令的执行结果 执行状态返回值: 取决于函数中执行的最后一条语句,最后一条执行成功返回0,否刚返回其它 反回值可以自定义:使用return N # N为自定义返回值.注意:函数中使用了return后会退出该函数,执行函数下面的其它命令。
#/bin/bash#getline (){while read linedolet i++ if (( $i> 10 ));then return 4 fidone < $1echo "$1 have $i line"}getline $1if [ $? -eq 4 ];then ## 获取 getline 函数的反回值是否等于4 echo '行数过多,放弃读取'else echo 'getline函数执行完毕'fi
函数可以接受参数:
在函数体可以使用类似脚本调用位置参数一样的参数 $1, $2, ... $# $*, $@如果想把脚本的全部位置参数,统统传递给脚本中某函数使用,怎么办? 使用$*传递,如果想一个一个使用,则判断$#有几个,再循环一个一个的使用
如果在函数中使用变量:变量作用域
在函数中使用了在主程序中声明的变量,重新赋值会直接修改主程序中的变量; 如果不期望函数与主程序中的变量冲突,函数中使用变量都用local修饰;即使用局部变量; 在函数中使用了在主程序中没有声明的变量,在函数执行结束后即被撤消,无论是否使用local修饰符;应用示例:
写一个脚本,完成如下功能
1、显示如下菜单disk) show disk infomem) show memory infocpu) show cpuinfo2、显示用户选定的内容;#!/bin/bash#showMenu() { ## 第一种定义函数名的方法cat << EOFdisk) show disk infomem) show memory infocpu) show cpuinfoquit) exit scriptEOF}function main { ## 第二种调用函数的方法while true ;doshowMenu ## 调用定义的函数,函数内嵌函数。read -p "please enter menu option: " optionoption=`echo $option | tr 'A-Z' 'a-z'` case $option in disk) df -h ;; mem) free -m ;; cpu) cat /proc/cpuinfo ;; quit) exit 0 ;; *) echo "error option." esacdone}main ## 调用函数
写一个脚本,判定172.16.0.0网络内有哪些主机在线,在线的用绿色显示,不在线的用红色显示;要求,编程中使用函数;
#!/bin/bash#cnetping() { for i in {1..254};do ping -c 1 -w 1 $1.$i done}# cnetping 192.168.1.= 192.168.1+$1bnetping() { for j in {0..255};do cnetping $1.$j done}# bnetping 172.16. = 172.16+$j+$ianetping() { for k in {0..255};do bnetping $1.$k done}# anetping 10.=10.$k+$j+$iread -p "enter IPaddr: " IPaddrNetType=`echo $IPaddr | cut -d'.' -f1`if [ $NetType -ge 0 -a $NetType -le 127 ];then anetping `echo $IPaddr | awk -F'.' '{print $1}'`elif [ $NetType -ge 128 -a $NetType -le 191 ];then bnetping `echo $IPaddr | awk -F'.' '{print $1"."$2}'`elif [ $NetType -ge 192 -a $NetType -le 223 ];then cnetping `echo $IPaddr | awk -F'.' '{print $1"."$2"."$3}'`else echo "error IP"fi
写一个脚本,完成如下功能(使用函数):
1、提示用户输入一个可执行命令;2、获取这个命令所依赖的所有库文件(使用ldd命令);3、复制命令至/mnt/sysroot/对应的目录中 解释:假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;4、复制各库文件至/mnt/sysroot/对应的目录中,其要求命令;#!/bin/bash#copytarget=/mnt/sysroot[ -d $copytarget ] || mkdir -p $copytargetcommand () {if which $COMMAND &> /dev/null;then COMMAND=`which --skip-alias $COMMAND`else return 5fi}copycommand() { command_dir=${copytarget}`dirname $COMMAND` [ -d ${command_dir} ] || mkdir -p ${command_dir} [ -f ${copytarget}${COMMAND} ] || cp $COMMAND ${command_dir}}copylib() { for i in `ldd $COMMAND | grep -o "/[^[:space:]]\{1,\}"`;do libdir=${copytarget}`dirname $i` [ -d $libdir ] || mkdir $libdir [ -f ${copytarget}${i} ] || cp $i $libdir done}while true;doread -p "please enter command: " COMMAND[ "$COMMAND" == 'quit' ] && exit 7 command[ $? -eq 5 ] && continue copycommand copylibdone
写一个脚本,完成如下功能(使用函数):
1、脚本使用格式:mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile2、如果文件事先不存在,则创建;且前几行内容如下所示:#!/bin/bash# Description: script description# Author: script author#3、如果事先存在,但不空,且第一行不是“#!/bin/bash”,则提示错误并退出;如果第一行是“#!/bin/bash”,则使用vim打开脚本;把光标直接定位至最后一行4、打开脚本后关闭时判断脚本是否有语法错误 如果有,提示输入y继续编辑,输入n放弃并退出; 如果没有,则给此文件以执行权限;#!/bin/bash##mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefilewhile true;do[ $# -lt 1 ] && breakcase $1 in -D|--description) description=$2 shift 2 ;; -A|--author) author=$2 shift 2 ;; *) file=$1 shift 1esacdone[ -d `dirname $file` ] || mkdir `dirname $file`if ! [ -e $file ];then echo -e "#!/bin/bash\n# Description:${description}\n# Author:${author}\n#" > $fileelif [ -f $file ];then head -1 $file | grep '#!/bin/bash' &> /dev/null && vim +$ $fileelse echo " error $file not scripts file."; exit 7fi## 检查脚本while true;doif bash -n $file &> /dev/null;then chmod +x $file breakfiread -p "enter Y contiue ,N exit script!" option case $option in y|Y) vim $file ;; n|N) exit 8 ;; *) echo "error option" esacdone