bash支持使用函数,函数出现的地方,而自动被替换成函数定义的代码,一个函数定义后可以多次被重复使用,大大减少代码量
函数定义格式:
第一种
FuncName() { 函数体 }
第二种
function FuncName { 函数体 }
函数有两种返回值:
正常返回的数据:
函数中的打印语句,如echo或print
函数中命令的执行结果
执行状态返回值:
取决于函数中执行的最后一条语句,最后一条执行成功返回0,否刚返回其它
反回值可以自定义:使用return N # N为自定义返回值
函数可以接受参数:
在函数体可以使用类似脚本调用位置参数一样的参数
$1, $2, ...
$#
$*, [email protected]
如果想把脚本的全部位置参数,统统传递给脚本中某函数使用,怎么办?
使用$*传递,如果想一个一个使用,则判断$#有几个,再循环一个一个的使用
如果在函数中使用变量:变量作用域
在函数中使用了在主程序中声明的变量,重新赋值会直接修改主程序中的变量;
如果不期望函数与主程序中的变量冲突,函数中使用变量都用local修饰;即使用局部变量;
在函数中使用了在主程序中没有声明的变量,在函数执行结束后即被撤消,无论是否使用local修饰符;
应用示例:
写一个脚本,完成如下功能
1、显示如下菜单
disk) show disk info
mem) show memory info
cpu) show cpuinfo
2、显示用户选定的内容;
#!/bin/bash # showMenu() { ## 第一种定义函数名的方法 cat << EOF disk) show disk info mem) show memory info cpu) show cpuinfo quit) exit script EOF } function main { ## 第二种调用函数的方法 while true ;do showMenu ## 调用定义的函数,函数内嵌函数。 read -p "please enter menu option: " option option=`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." esac done } 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+$1 bnetping() { for j in {0..255};do cnetping $1.$j done } # bnetping 172.16. = 172.16+$j+$i anetping() { for k in {0..255};do bnetping $1.$k done } # anetping 10.=10.$k+$j+$i read -p "enter IPaddr: " IPaddr NetType=`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 $copytarget command () { if which $COMMAND &> /dev/null;then COMMAND=`which --skip-alias $COMMAND` else return 5 fi } 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;do read -p "please enter command: " COMMAND [ "$COMMAND" == ‘quit‘ ] && exit 7 command [ $? -eq 5 ] && continue copycommand copylib done
写一个脚本,完成如下功能(使用函数):
1、脚本使用格式:
mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile
2、如果文件事先不存在,则创建;且前几行内容如下所示:
#!/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/somefile while true;do [ $# -lt 1 ] && break case $1 in -D|--description) description=$2 shift 2 ;; -A|--author) author=$2 shift 2 ;; *) file=$1 shift 1 esac done [ -d `dirname $file` ] || mkdir `dirname $file` if ! [ -e $file ];then echo -e "#!/bin/bash\n# Description:${description}\n# Author:${author}\n#" > $file elif [ -f $file ];then head -1 $file | grep ‘#!/bin/bash‘ &> /dev/null && vim +$ $file else echo " error $file not scripts file."; exit 7 fi ## 检查脚本 while true;do if bash -n $file &> /dev/null;then chmod +x $file break fi read -p "enter Y contiue ,N exit script!" option case $option in y|Y) vim $file ;; n|N) exit 8 ;; *) echo "error option" esac done