放假这几天没干别的好事,除了学习审计的内容之外,终于啃完了这本书的第二章节。对于bash的一些基本编程算是掌握了五成吧。很遗憾自己没有把第二章的程序设计搞定,欣慰的是,前面那个小程序设计做到了独立完成,期间也查了一些相关知识。大程序开始自己是有动手的想做一个小程序的演变版本,结果是个四不像,最后干脆连代码都通过不了了。真是汗!
学到现在学了两个章节,这本书,必须说,又是一本好书,适合有点程序基础(任何程序语言基础)的人自学用。虽然Linux的系统在中国并不普及,但是个人还是想好好学一下。不为别的,就为其中的美妙思路。Linux是个有意思的游戏。所以其实我之前说学了C之后走了Linux的“弯”路,到我现在这情况,也就不算弯路了。
以下为前两章比较大的收获。点到即止。
第一章新知识总结:page 44实例部分教了怎么建立archive for source files。
第二章Shell syntax很有用教了各种 -eq -el等等的东西(书上内容多得多),可作将来备忘。 好了,以下我就拿最后那个大程序的笔记作谢幕了。其中各种命令,参数,符号都很有意思哦。标出的注释是我个人一开始没有理解好的地方。
#!/bin/bash
#Very simple example shell script for managing a CD collection.
#这个练习在Linux程序设计第二章最后一节。
#笔记
#Global variable
menu_choice=""
current_cd=""
title_file="title.cdb"
tracks_file="tracks.cdb"
temp_file="/tmp/cdb.¥¥" # ¥¥表明了当前进程号-PID。只能用人民币符号 其实是美元符号,但是会被解读掉。
trap 'rm -f $temp_file' EXIT
#Define Functions
get_return() { # 关于get_return就是读取了x 以后它就回上一级程序
echo -e "Press return \c"
read x
return 0
}
get_confirmed() {
echo -e "Are you sure? \c"
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() { # Menu的外观
clear
echo "Options :-"
echo
echo " a) Add new CD"
echo " f) Find CD"
echo " c) Count the CDs and tracks in the catalog"
if [ "$cdcatnum" != "" ]; then
echo " l) List tracks on $cdtitle"
echo " r) Remove $cdtitle"
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 # Append到文件后面。
return
}
insert_track() {
echo $* >> $tracks_file
return
}
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 # 当这个tmp(原输入string)不等于这个cdttitle
echo "Sorry, no commas allowed"
continue
fi
if [ -n "$cdttitle" ]; then # 如果cdttitle非空
if [ "$cdttitle" != "q" ]; then # 且不为零
insert_track $cdcatnum,$cdtrack,$cdttitle
fi
else
cdtrack=$((cdtrack-1))
fi
cdtrack=$((cdtrack+1))
done
}
add_records() {
#Prompt for the initial information
echo -e "Enter catalog name \c"
read tmp
cdcatnum=${tmp%%,*}
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_confirmed; then
insert_title $cdcatnum,$cdtitle,$cdtype,$cdac
add_record_tracks
else
remove_records
fi
return
}
find_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 # 把用grep在位于title_file文件中找到的CD的结果写去temp_file
set $(wc -l $temp_file) # wc -l 那块是为了显示这个temp_file里面的行数。例如,当多于等于2时,程序无法决定你要哪个CD
linesfound=$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
echo "Sorry, could not extract catalog field from $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? \c"
read x
if [ "$x" = "y" ]; then
echo
list_tracks
echo
fi
fi
return 1
}
update_cd() {
if [ -z "$cdcatnum" ]; then
echo "You must select a CD first"
find cd n
fi
if [ -n "$cdcatnum" ]; then
echo "Current tracks are :-"
list_tracks
echo
echo "This will re-enter the tracks for $cdtitle"
get_confirmed && {
grep -v "^${cdcatnum}," $tracks_file > $temp_file # 找出符合cdcatnum条件(即非那个num)的track,把他们放进temp_file。
mv $temp_file $tracks_file # temp_file里面所有东西移去tracks_file,此时选定的cdcatnum也就不会在了,因为被覆盖了
echo
add_record_tracks
}
fi
return
}
count_cds() {
set $(wc -l $title_file)
num_title=$1
set $(wc -l $tracks_file)
num_tracks=$1
echo found $num_titles CDs, with a total of $num_tracks tracks
get_return
return
}
#I delete grep -v...here.
remove_records() {
if [ -z "$cdcatnum" ]; then
echo "You must select a CD first"
find_cd n
fi
if [ -n "$cdcatnum" ]; then
echo "You are about to delete $cdtitle"
get_confirmed && {
grep -v "^${cdcatnum}," $title_file > $temp_file
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 { # if, else后面的括号前面一定要有空格。
echo
echo "$cdtitle :-"
echo
cut -f 2- -d , $temp_file # 以,为分隔符,第2个field。例如:CD123,2,Sing a Song。这里就返回了 ,Sing a Song。向字符串数组,从零开始走起。
echo
} | ${PAGER:-more} # 如果当前屏幕页面设置已被定义则执行当前页面设置,如限制了输出内容。不然的话,就将启用more这个命令来定义屏幕显示结果。
fi
fi
get_return
return
}
rm -f $temp_file
if [ ! -f $title_file ]; then
touch $title_file
fi
if [ ! -f $tracks_file ]; then
touch $tracks_file
fi
# 正式功能
clear
echo
echo
echo "Mini CD manager"
sleep 2
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
最后,我要吐槽CSDN,为啥没有Shell语言的编辑功能?如果有懂行的看见,也请麻烦教我调一下。