函数是实现模块化编程的工具
函数:function:功能组件
函数就是:将一个复杂问题分给成多个小的简单问题的基本组件,实现最小话的代码冗余
特点:可被调用:函数有函数名
函数出现的地方,而自动被替换成函数定义的代码
函数定义
语法:
FuncName() {
函数体
}
function FuncName {
函数体
}
函数有两种返回值:
正常返回数据:
函数中的打印语句,有echo或print
函数中命令的执行结果
执行状态返回值:
1.取决于函数中执行的最后一条语句
2.自定义:return N
函数可以接受参数:
在函数体重可以使用类似脚本调用参数一样的参数
$1 $2
$#
$* $@
#!/bin/bash
ShowUserInfo() {
[ $# -lt 1 ] && return 6
grep "^$1\>" /etc/passwd | cut -d: -f3,7 || return 10
}
function main {
while true;do
read -p "enter a name: " userName
if [ "$userName" == "quit" ];then
exit 0
fi
if ! id $userName &> /dev/null;then
echo "No such user,please again"
continue
fi
ShowUserInfo $userName
done
}
main
写一个脚本:
1.显示如下菜单
disk)show disk info
mem)show memory info
cpu) show cpu info
2,显示用户选定内容
#!/bin/bash
#
display() {
cat << EOF
disk) show disk info
mem) show memory info
cpu) show cpuinfo
EOF
}
disk(){
df -h
}
mem(){
free -m
}
cpu(){
cat /proc/cpuinfo
}
main() {
while true; do
display
read -p "input you select: " select
[ "$select" == "quit" ] && exit 0
case $select in
mem)
mem
;;
disk)
disk
;;
cpu)
cpu
;;
*)
echo "erro select"
esac
done
}
重点内容如何在函数中使用变量:变量作用域
在函数中使用了在主程序中声明的变量:重新赋值会影响主程序中的变量
如果不期望函数与主程序中的变量冲突,函数中使用变量都用local装饰;即使用局部变量
无论是在函数中还是主程序中使用未声明的变量,全部当做全局变量
练习:写一个脚本,判定172.16.0.0网络内有哪些主机在线,在线的用绿色显示,不在线的用红色显示;要求,编程中使用函数;
#!/bin/bash
one(){
for i in {1..254};do
ping -c -1 w 1 $1.$i
}
two(){
for j in {1..254};do
one $i.$j
if [[ $? -eq 0 ]];then
echo -e -n "\033[32mping 172.16.$i.$j ke da !\033[0m\n"
else
echo -e -n "\033[31mping 172.16.$i.$j bu ke da !\033[0m \n"
fi
done
}
练习:写一个脚本,完成如下功能(使用函数):
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
#
target=/mnt/sysroot
clearCmd() {
if which $cmd &> /dev/null; then
cmdPath=`which --skip-alias $cmd`
else
echo "No such command"
return 5
fi
}
cmdCopy() {
cmdDir=`dirname $1`
[ -d ${target}${cmdDir} ] || mkdir ${target}${cmdDir}
[ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
}
libCopy() {
for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`;do
libDir=`dirname $lib`
[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
[ -f ${target}${lib} ] || cp $lib ${target}${libDir}
done
}
while true; do
read -p "Entero a command: " cmd
if [ "$cmd" == "quit" ];then
echo "quit"
exit 6
fi
if ! which $cmd &> /dev/null;then
echo "comamnd is not exist"
continue
fi
clearCmd $cmd
cmdCopy $cmdPath
libCopy $cmdPath
done
#!/bin/bash
options(){
for i in $*;do
dirname=`dirname $i`
[ -d /mnt/sysroot$dirname ] || mkdir -p /mnt/sysroot$dirname
[ -f /mnt/sysroot$i ]||cp $i /mnt/sysroot$dirname/
done
}
while true;do
read -p "Enter a command : " pidname
[[ "$pidname" == "quit" ]] && echo "Quit " && exit 0
bash=`which --skip-alias $pidname`
if [[ -x $bash ]];then
options `/usr/bin/ldd $bash |grep -o "/[^[:space:]]\{1,\}"`
options $bash
else
echo "PLZ a command!"
fi
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
read -p "Enter a file: " filename
options(){
if [[ $# -ge 0 ]];then
case $1 in
-D|--description)
authname=$2
descr=$4
;;
-A|--author)
descr=$2
authname=$4
;;
esac
fi
}
command(){
if bash -n $filename &> /dev/null;then
chmod +x $filename
else
while true;do
read -p "[y|n]:" option
case $option in
y)
vim + $filename
;;
n)
exit 8
;;
esac
done
fi
exit 6
}
oneline(){
if [[ -f $filename ]];then
if [ `head -1 $filename` == "#!/bin/bash" ];then
vim + $filename
else
echo "wrong..."
exit 4
fi
else
touch $filename && echo -e "#!/bin/bash\n# Description: $2\n# Author: $4" > $filename
vim + $filename
fi
command
}
options $*
oneline