如何将shell script功能模块化,并且对外留出函数和参数接口

如何将shell script功能模块化,并且对外留出函数和参数接口。要写出这种高质量的模块化的东西,需要对要写的这一块的业务非常理解,知道哪些是通用的,哪些是不通用的。从而将其分离,废话不多说直接看一个我感觉很牛B的脚本。

以下脚本的作用
我新写了一个内核device driver模块,下面的脚本是尝试将我的模块,加载模块,在/dev目录下创建结点+++删除文件,卸载模块

参数接口部分

#!/bin/bash
#
Sample init script for the a driver module <rubini@linux.it>

DEVICE="scull"
SECTION="misc"

# The list of filenames and minor numbers: $PREFIX is prefixed to all names
PREFIX="scull"
FILES=" 0 0 1 1 2 2 3 3 priv 16
pipe0 32 pipe1 33 pipe2 34 pipe3 35
single 48 uid 64 wuid 80
"

INSMOD=/sbin/insmod; # use /sbin/modprobe if you prefer

function device_specific_post_load () {
true; # fill at will
}
function device_specific_pre_unload () {
true; # fill at will
}

具体介绍:

  • DEVICE是加载的模块的名字。必须和在driver代码中注册的名字相同。
  • FILES是加载的模块生成的文件参数。(文件名字后缀+minor_num)。

最虎的是:
留出了2个函数接口,让我们面向接口编程
留出的2个接口是device_specific_post_load 和 device_specific_pre_unload分别是insmod加载之后想做什么?rmmod之后想做什么?这种面向接口编程主要是对实际应用的人考虑的比较周到

 

下面这个是一些不轻易被用户改变的参数

# Everything below this line should work unchanged for any char device.
#
Obviously, however, no options on the command line: either in
#
/etc/${DEVICE}.conf or /etc/modules.conf (if modprobe is used)

# Optional configuration file: format is
#
owner <ownername>
#
group <groupname>
#
mode <modename>
#
options <insmod options>
CFG=/etc/${DEVICE}.conf

# kernel version, used to look for modules
KERNEL=`uname -r`

#FIXME: it looks like there is no misc section. Where should it be?
MODDIR="/lib/modules/${KERNEL}/kernel/drivers/${SECTION}"
if [ ! -d $MODDIR ]; then MODDIR="/lib/modules/${KERNEL}/${SECTION}"; fi

# Root or die
if [ "$(id -u)" != "0" ]
then
echo "You must be root to load or unload kernel modules"
exit 1
fi

# Read configuration file
if [ -r $CFG ]; then
OWNER=`awk "\\$1==\"owner\" {print \\$2}" $CFG`
GROUP=`awk "\\$1==\"group\" {print \\$2}" $CFG`
MODE=`awk "\\$1==\"mode\" {print \\$2}" $CFG`
# The options string may include extra blanks or only blanks
OPTIONS=`sed -n '/^options / s/options //p' $CFG`
fi


主要包括取得config file里面的用户权限信息,检查用户是否为root用户。

# Create device files
function create_files () {
cd /dev
local devlist=""
local file
while true; do
if [ $# -lt 2 ]; then break; fi
file="${DEVICE}$1"
mknod $file c $MAJOR $2
devlist="$devlist $file"
shift 2
done
if [ -n "$OWNER" ]; then chown $OWNER $devlist; fi
if [ -n "$GROUP" ]; then chgrp $GROUP $devlist; fi
if [ -n "$MODE" ]; then chmod $MODE $devlist; fi
}

# Remove device files
function remove_files () {
cd /dev
local devlist="" //函数里的变量尽量使用local关键字声明,代表是一个局部变量
local file
while true; do
if [ $# -lt 2 ]; then break; fi
file="${DEVICE}$1"
devlist="$devlist $file"
shift 2
done
rm -f $devlist
}
# Load and create files
function load_device () {

if [ -f $MODDIR/$DEVICE.o ]; then
devpath=$MODDIR/$DEVICE.o
else if [ -f ./$DEVICE.o ]; then
devpath=./$DEVICE.o
else
devpath=$DEVICE; # let insmod/modprobe guess
fi; fi
if [ "$devpath" != "$DEVICE" ]; then
echo -n " (loading file $devpath)"
fi

if $INSMOD $devpath $OPTIONS; then
MAJOR=`awk "\\$2==\"$DEVICE\" {print \\$1}" /proc/devices`
remove_files $FILES
create_files $FILES
device_specific_post_load
else
echo " FAILED!"
fi
}

# Unload and remove files
function unload_device () {
device_specific_pre_unload
/sbin/rmmod $DEVICE
remove_files $FILES
}

上面的4个是函数。create_files, remove_files, load_device, unload_device
下面的就是case语句进行选择运行了。

case "$1" in
start)
echo -n "Loading $DEVICE"
load_device
echo "."
;;
stop)
echo -n "Unloading $DEVICE"
unload_device
echo "."
;;
force-reload|restart)
echo -n "Reloading $DEVICE"
unload_device
load_device
echo "."
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload}"
exit 1
esac

exit 0



 



posted @ 2011-11-01 17:26  Jack204  阅读(1697)  评论(0编辑  收藏  举报