bash编程之 函数

函数:代码复用 模块编程

语法:

	function f_name {
		函数体
	}

	f_name() {
		函数体
	}

调用:使用函数名

函数名出现的地方,会被自动替换为函数代码;

练习:利用函数改写此前的服务脚本:

	#!/bin/bash
	#
	prog=`basename $0`
	lockfile=/var/lock/subsys/$prog

	start() {
		if [ -e $lockfile ]; then
			echo "$prog is already running."
		else
			touch $lockfile
			[ $? -eq 0 ] && echo "Starting $prog finished."
		fi
	}

	stop() {
		if [ -e $lockfile ]; then
			rm -f $lockfile
			[ $? -eq 0 ] && echo "Stoping $prog finished."
		else
			echo "$prog is stopped yet."
		fi
	}

	case $1 in
	"start")
		start ;;
	"stop")
		stop ;;
	"restart")
		stop
		start ;;
	*)
		echo "Usage: $prog {start|stop|restart}"
		exit 1
	esac        

函数的返回值:

函数的执行结果返回值:

函数中使用打印语句:echo, printf

函数体中OS命令执行结果的输出

函数的退出状态码:

默认取决于函数体执行的最后一个命令的退出状态码;

自定义退出状态码:

return [0-255]

注意:函数体运行时,一旦遇到return语句,函数即返回;

函数可接受参数:

传递参数给函数:调用函数时,在函数名后给出参数列表即可;例如“testfunc arg1 arg2 arg3”

在函数体中可使用$1, $2,...来调用传递过来的各参数;

可使用类似脚本的特殊变量:

$*, $@: 一次性获取参数列表:

$#: 参数的个数

#!/bin/bash
#
showuserinfo() {
	[ $# -lt 1 ] && return 1

	! id $1 &> /dev/null && return 2

	grep "^$1\>" /etc/passwd | cut -d: -f7
	[ $? -eq 0 ] && return 0 || return 3
}

while true; do
	read -p "Enter a username: " username
	[ "$username" == 'quit' ] && break
	showuserinfo $username
	[ $? -ne 0 ] && echo "There is something wrong."
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

[ -d $target ] || mkdir $target

preCmd() {
	if which $1 &> /dev/null; then
		cmdpath=$(which --skip-alias $1)
		return 0
	else
		echo "No such command."
		return 1
	fi
}

cmdCopy() {
	cmddir=$(dirname $cmdpath)
	[ -d $target/$cmddir ] || mkdir -p $target/$cmddir
	[ -f $target/$cmdpath ] || cp $1 $target/$cmddir
	return 0
}

libCopy() {
	for lib in $(ldd $1 | grep -E -o "/[^[space::]]+"); do
		libdir=$(dirname $lib)
		[ -d $target/$libdir ] || mkdir -p $target/$libdir
		[ -f $target/$lib ] || cp $lib $target/$libdir
	done
	return 0
}

main() {
	while true; do
		read -p "Plz enter a command(quit): " cmd
		[ "$cmd" == 'quit' ] && break
		preCmd $cmd
		if [ $? -eq 0 ]; then
			cmdCopy $cmdpath
			libCopy $cmdpath
		fi
	done
}

main

函数递归:

函数直接或间接调用函数自身;

1 1 2 3 5 8 13

阶乘:10!

n(n-1)!

n(n-1)(n-2)!

阶乘函数:

	fact() {
		if [ $1 -eq 0 -o $1 -eq 1 ]; then
			echo 1
		else
		   echo $[$1*$(fact $[$1-1])]
		fi
	}

猜你喜欢

转载自oracle-api.iteye.com/blog/2365434