bash支持使用函数,函数出现的地方,而自动被替换成函数定义的代码,一个函数定义后可以多次被重复使用,大大减少代码量


函数定义格式:

第一种

FuncName() {
    函数体
        }

第二种

function FuncName {
    函数体
}


函数有两种返回值:
     正常返回的数据:
           函数中的打印语句,如echo或print
           函数中命令的执行结果
     执行状态返回值:
          取决于函数中执行的最后一条语句,最后一条执行成功返回0,否刚返回其它
          反回值可以自定义:使用return N   # N为自定义返回值.

注意:函数中使用了return后会退出该函数,执行函数下面的其它命令。

#/bin/bash
#
getline (){
while read line
do
let i++
  if (( $i> 10 ));then
        return 4
  fi
done < $1
echo "$1 have $i line"
}

getline $1

if [ $? -eq 4 ];then    ## 获取 getline 函数的反回值是否等于4
 echo '行数过多,放弃读取'
else
 echo 'getline函数执行完毕'
fi

函数可以接受参数:
        在函数体可以使用类似脚本调用位置参数一样的参数
        $1, $2, ...
        $#
        $*, $@

    
    如果想把脚本的全部位置参数,统统传递给脚本中某函数使用,怎么办?
            使用$*传递,如果想一个一个使用,则判断$#有几个,再循环一个一个的使用


如果在函数中使用变量:变量作用域
    在函数中使用了在主程序中声明的变量,重新赋值会直接修改主程序中的变量;
        如果不期望函数与主程序中的变量冲突,函数中使用变量都用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