[分享]学习一篇shell综合实例

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
casual0402
帖子: 116
注册时间: 2008-04-05 14:18
来自: Fujian,China
联系:

[分享]学习一篇shell综合实例

#1

帖子 casual0402 » 2008-11-20 13:29

主要是一个文本型CD数据库,在学习shell时对它进行注释和理解。现在分享一下。希望得到各位的指点,谢谢。

代码: 全选

#!/bin/sh

#定义全局变量
menu_choice=""
current_cd=""
title_file="title.cdb"   #标题文件
tracks_file="track.cdb"   #曲目文件
temp_file=/tmp/cdb.$$    #临时文件
trap 'rm -f $temp_file' EXIT    #当按下Ctrl+C组合键的中断处理,保证删除临时文件再退出
#全局变量定义结束

#定义函数开始

get_return() {   # get_return() 函数
	echo -e "Press return 请按回车键 \c"   #按回车键返回
	read x
	return 0
}

get_confirm() {         # get_confirm() 函数  用于确认用户操作或者确认信息
	echo -e "Are you sure? \c"   #有些shell可能不支持echo -e
	while true
	do
		read x         #读入用户输入
		case "$x" in
			y | yes | Y | Yes | YES )
				return 0;;
			n | no | N | No | NO )
				echo
				echo "Cancelled"
				return 1;;
			*) echo "Please enter yes or no" ;;
		esac
	done
}

set_menu_choice() {   # 设置菜单选项
	clear
	echo "Options :-"
	echo 
	echo "	a) Add new CD 添加一张新CD"
	echo "	f) Find CD 查找CD"
	echo "	c) Count the CDs and tracks in the catalog 在目录中统计CD和曲目的数目"
	if [ "$cdcatnum" != "" ]; then      #如果CD唱片目录不为空
		echo "	l) List tracks on $cdtitle 根据CD标题列出曲目"
		echo "	r) Remove $cdtitle 删除CD标题"
		echo "	u) Update track information for $cdtitle 更新曲目信息"
	fi
	echo "	q) 	Quit 退出"
	echo
	echo -e "Please enter choice then press return \c"
	read menu_choice      #读入用户选项
	return
}

insert_title() {
	echo $* >> $title_file
	return
}

insert_track() {      #插入曲目
	echo $* >> $tracks_file   #追加到$tracks_file
}

add_record_tracks() {     #添加曲目的函数
	echo "Enter track information for this CD"
	echo "When no more tracks enter q"
	cdtrack=1
	cdttitle=""
	while [ "$cdttitle" != "q" ]
	do
		echo -e "Track $cdtrack,track title? 输入曲目标题\c"        #################   错误已改正   ################
		read tmp
		cdttitle=${tmp%%,*}  #从尾部开始查找匹配 ,* 的格式并删除,返回剩余部分赋值给$cdttitle
		if [ "$tmp" != "$cdttitle" ]; then   #如果删除逗号后二者不相符,则输出提示
			echo "$tmp\n$cdttitle"
			echo "Sorry,no commas allowed 不允许包含逗号"
			continue
		fi                                   #################   错误已改正   ################
		
		if [ -n "$cdttitle" ]; then  # 如果$cdttitle 长度非零返回真,如果是 -z 替换 -n 表示长度为零时返回真
			if [ "$cdttitle" != "q" ]; then      #如果输入不为q
				insert_track $cdcatnum,$cdtrack,$cdttitle
			fi
		else
			cdtrack=$((cdtrack-1))     # $(($cdtrack-1))  据我测试是等价
		fi
		cdtrack=$((cdtrack+1))
	done
}

add_records() {     #添加记录的函数
	# Prompt for the initial information   初始化信息提示
	
	echo -e "Enter catalog name 请输入目录名称 \c"
	read tmp        #读入一个临时变量
	cdcatnum=${tmp%%,*}    #从尾部开始搜索匹配并删除,返回赋值给cdcatnum
	
	echo -e "Enter title 请输入标题 \c"
	read tmp
	cdtitle=${tmp%%,*}
	
	echo -e "Enter type 请输入类型 \c"
	read tmp
	cdtype=${tmp%%,*}
	
	echo -e "Enter artist/composer 请输入作曲或者作词或者演唱者 \c"
	read tmp
	cdac=${tmp%%,*}
	
	#Check that they want to enter the information 输出确认信息
	
	echo About to add new entry
	echo "$cdcatnum $cdtitle $cdtype $cdac"
	
	#If confirmed then append it to the titles file   如果确认则添加信息
	
	if get_confirm ; then  #调用get_confirm函数
		insert_title $cdcatnum,$cdtitle,$cdtype,$cdac
		add_record_tracks
	else
		remove_records
	fi
	
	return
}

find_cd() {       #查找CD函数
	if [ "$1" = "n" ]; then
		asklist=n
	else
		asklist=y
	fi
	cdcatnum=""
	echo -e "Enter a string to search for in the CD titles 请输入要查找的唱片标题 \c"
	read searchstr
	if [ "$searchstr" = "" ]; then
		return 0
	fi
	
	grep "$searchstr" $title_file > $temp_file     #从$title_file中搜索与搜索关键字匹配的向,然后重定向到$temp_file
	
	set $(wc -l $temp_file)      # 括号中 wc -l 是统计行数
	linesfound=$1         # $1 表示函数的第一个参数,依此类推
	
	case "$linesfound" in  #看查找到几项匹配的记录
		0)	echo "Sorry,nothing found"
				get_return
				return 0
				;;
		1)	;;
		2)	echo "Sorry,not unique"
				echo "Found the following"
				cat $temp_file
				get_return
				return 0
		esac
		
		IFS=","      #设置分割符为逗号
		read cdcatnum cdtitle cdtype cdac < $temp_file
		IFS=" "      #设置分割符为空格
		if [ -z "$cdcatnum" ]; then       #如果$cdcatnum的长度为零则返回真
			echo "Sorry,could not extract catalog field from $temp_file 不能从 $temp_file 中提取出目录"
			get_return       #返回
			return 0
		fi
		
		echo 
		echo Catalog number目录数量: $cdcatnum
		echo Title标题: $cdtitle
		echo Type类型: $cdtype
		echo Artist/Composer艺术家/作者: $cdac
		echo
		get_return
		
		if [ "$asklist" = "y" ]; then
			echo -e "View tracks for this CD? 查看这张CD的曲目? \c"
				read x
			if [ "$x" = "y" ]; then
				echo
				list_tracks
				echo
			fi
		fi
	return 1
}

update_cd() {     #更新CD的函数
	if [ -z "$cdcatnum" ]; then    #如果$cdcatnum为零则返回真
		echo "You must select a CD first你必须选择一张CD"
		find_cd n     #调用find_cd()函数,参数为n
	fi
	
	if [ -n "$cdcatnum" ]; then   #如果$cdcatnum不为零则返回真
		echo "Current tracks are 现在的曲目有 :-"
		list_tracks         #调用列曲目函数
		echo
		echo "This will re-enter the tracks for $cdtitle 重输入曲目"
		get_confirm && { #确认而且……
			grep -v "^${cdcatnum}," $tracks_file > $temp_file   #参数 -v 对匹配模式取反,即搜索不匹配行;此外 -i表示忽略大小写,-l表示只输出包含匹配行的文件,而不输出真正的匹配行,-c表示输出匹配行的数目
			mv $temp_file $tracks_file   #重命名
			echo
			add_record_tracks   #添加曲目
		}
	fi
	return 
}

count_cds() {
	set $(wc -l $title_file)   #统计$title_file文件的行数并返回,并利用set命令将其设置为$1
	num_titles=$1
	set $(wc -l $tracks_file)
	num_tracks=$1
	echo found $num_titles CDs,with a total of $num_tracks tracks
	get_return
	return
}

remove_records() {
	if [ -z "$cdcatnum" ]; then      #如果$cdcatnum为零则返回真
		echo You must select a CD first
		find_cd n
	fi
	if [ -n "$cdcatnum" ]; then         #如果不为零则返回真
		echo "You are about to delete $cdtitle"
		get_confirm &&  {
			grep -v "^${cdcatnum}," $title_file > $temp_file      #-v表示取反模式开启
			mv $temp_file $title_file
			grep -v "^${cdcatnum}," $tracks_file > $temp_file
			mv $temp_file $tracks_file
			cdcatnum=""
			echo Entry removed
		}
		get_return
	fi
	return
}

list_tracks() {
	if [ "$cdcatnum" = "" ]; then
		echo no CD selected yet
		return
	else
		grep "^${cdcatnum}," $tracks_file > $temp_file
		num_tracks=$(wc -l $temp_file)
		if [ "$num_tracks" = "0" ]; then
			echo "no tracks found for $cdtitle"
		else {
			echo 
			echo "$cdtitle :-"
			echo
			cut -f 2- -d , $temp_file
			echo
		} | ${PAGER:-more}    #如果PAGER未被设置则取默认值more
		fi
	fi
	get_return
	return
}

# 函数定义结束

#开始主函数部分

rm -f $temp_file      #删除临时文件 $temp_file
if [ ! -f $title_file ]; then       #如果$title_file不存在
	touch $title_file          #创建$title_file
fi
if [ ! -f $tracks_file ]; then      #如果$tracks_file不存在
	touch $tracks_file            #创建$tracks_file
fi

# Now the application proper   程序OK了

clear           #清屏
echo
echo
echo "Mini CD manager"
sleep 1

quit=n         #默认设置quit标记为n,即不退出
while [ "$quit" != "y" ];
do
	set_menu_choice       #调用函数输出菜单
	case "$menu_choice" in
		a) add_records;;
		r) remove_records;;
		f) find_cd y;;
		u) update_cd;;
		c) count_cds;;
		l) list_tracks;;
		b) 
			echo
			more $title_file
			echo
			get_return;;
		q | Q ) quit=y;;
		*) echo "Sorry,choice not recognized选择无法被解释";;
	esac
done

#Tidy up and leave   清除干净再离开

rm -f $temp_file
echo "Finished"
exit 0
头像
HuntXu
帖子: 5776
注册时间: 2007-09-29 3:09

Re: [分享]学习一篇shell综合实例

#2

帖子 HuntXu » 2008-11-20 14:18

Beginning Linux Programming的例程吧?
HUNT Unfortunately No Talent...
头像
casual0402
帖子: 116
注册时间: 2008-04-05 14:18
来自: Fujian,China
联系:

Re: [分享]学习一篇shell综合实例

#3

帖子 casual0402 » 2008-11-20 20:31

HuntXu 写了:Beginning Linux Programming的例程吧?
yes
回复