SHELL程序的主要用途
在SHELL程序中不仅仅可以使用命令的集合,而且可而且可以安排自动化处理过程,因此可以通过编写SHELL程序使大量的任务执行实现自动化。SHELL比较擅长完成系统管理任务,尤其适合完成那些易用性、可维护性和便携性比执行效率更优先的任务。
SHELL程序的执行和调试
⑴在bash的SHELL程序设计中,程序必须以下面的行开始:
#!/bin/bash
复制代码
这里符号#!用来告诉系统,后面给出的参数是用来执行该文件的程序。
⑵当编辑完一个SHELL脚本后,要使该脚本能够执行,还必须使该脚本文件具有可执行权。需要执行命令:chmod +x filename
⑶在shell程序中,以#开头到一个行结束的句子表示注释信息。建议大家在编写shell程序时养成添加注释的习惯,因为注释不仅能给其他需要熟悉悉该程序的人以帮助,也能给出脚本编写者设计原理的提示。
⑷进行shell程序设计时,必定会用到变量。Shell编程中使用的变量有自己的特色,即所有的变量都是由字符串组成的,而且对变量无须进行声明,可直接进行变量赋值操作。
程序设计
1.创建以下菜单程序
USER:** HOST: **** DATE: xx/xx/20xx
A: 创建子目录并复制文件
B: 文件权限测试
C: 文件字符转换
D: 文件总数及文本行数统计
E: 文件查找
Q: 退出系统
———————————————————————————————
A:在用户家目录下创建名字为本人姓名的子目录,其存取权限为(drwxr-xr-x)。测试目录确实存在后,将已存在的file1、file2两文件拷入其中并分别显示两文件的内容。显示完成后将file1、file2两文件截断为大小为0的空文件。
B:测试当前用户对系统中某文件是否有r、w、x的权限,输出测试结果。
C:将file1、file2两文件中的小写字符转换为大写,并将转换后的内容分别写入新文件。判断上述操作成功后分别显示转换后的新文件的内容。
D:统计/dev目录下目录文件和符号链接文件的数目;统计系统中某文本文件中空行的行数;显示当前系统中所有环境变量。
E:在/dev目录下查找由s开头且文件名由5个字符组成的文件,找到后用file命令显示其文件类型。
#!/bin/bash
USER= 'whoami'
HOST=`hostname -s`
MYDATE=`date +%d/%m/%y`
while :
do
clear
cat << MAYDAY
-----------------------------------------------------------------
User:$USER Host:$HOST Date:$MYDATE
-----------------------------------------------------------------
A:创建子目录并复制文件
B:文件权限测试
C:文件字符转换
D:文件总数及文本行数统计
E:文件查找
Q:退出系统
------------------------------------------------------------------
MAYDAY
echo -n "Please Choose [A,B,C,D,E,Q]>"
read CHOICE
case $CHOICE in
A)
echo "A:创建子目录并复制文件"
echo "输入要创建的文件名:"
read FILE
mkdir $FILE
chmod 755 $FILE
test -d $FILE
if [ $? -eq 0 ]
then
cp file1 $FILE
cp file2 $FILE
echo "file1 内容"
cat file1
:>$FILE/file1
echo "file2 内容"
cat file2
:>$FILE/file2
fi
;;
B)
echo "B:文件权限测试"
echo "请输入要测试的文件绝对路径"
read NAME1
test -r $NAME1
if [ $? -eq 0 ]
then
echo "可读"
else
echo "不可读"
fi
test -w $NAME1
if [ $? -eq 0 ]
then
echo "可写"
else
echo "不可写"
fi
test -x $NAME1
if [ $? -eq 0 ]
then
echo "可执行"
else
echo "不可执行"
fi
;;
C)
echo "C:文件字符转换"
cat file1 | tr "[a-z]" "[A-Z]" >file1.tr
diff -q file1 file1.tr
if [ $? -eq 1 ]
then
echo "file1.tr 内容"
cat file1.tr
fi
cat file2 | tr "[a-z]" "[A-Z]" >file2.tr
diff -q file2 file2.tr
if [ $? -eq 1 ]
then
echo "file2.tr 内容"
cat file2.tr
fi
;;
D)
echo "/dev 目录下目录文件和符号链接文件的数目"
find /dev -type d | wc -l
find /dev -type l | wc -l
echo "file1 空行行数统计"
grep ^$ file1 | wc -l
echo "显示当前系统中所有环境变量"
env
;;
E)
echo "文件查找"
find /dev -name 's????' | xargs file
;;
Q)
exit 0
;;
*)
echo "输入不符合条件!
请回车后输入[A.B.C.D.E.Q]"
esac
read DD
done
复制代码
2.文件pc.txt中保存了三个班级的学生选课成绩
试编写一段shell程序对文件内容进行统计、计算后输出各个班级选课的学生人数及每班选课成绩的优秀率。
pc.txt
文件内容
如下:
Student1: 1301: 75
Student2: 1302: 96
Student3: 1303: 99
Student4: 1302: 93
Student5: 1303: 23
Student6: 1301: 77
#!/bin/bash
total1=`grep -F 1301 pc.txt|wc -l`
gradeA1=`grep -F 1301 pc.txt|awk -F: '$3 > 90'|wc -l`
rateA1=$(($gradeA1*100/$total1))
total2=`grep -F 1302 pc.txt|wc -l`
gradeA2=`grep -F 1302 pc.txt|awk -F: '$3 > 90'|wc -l`
rateA2=$(($gradeA2*100/$total2))
total3=`grep -F 1303 pc.txt|wc -l`
gradeA3=`grep -F 1303 pc.txt|awk -F: '$3 > 90'|wc -l`
rateA3=$(($gradeA3*100/$total3))
echo "各班选课人数及优秀率(90及以上为优秀)"
echo "1301班选课人数为$total1,优秀率为$rateA1%"
echo "1302班选课人数为$total2,优秀率为$rateA2%"
echo "1303班选课人数为$total3,优秀率为$rateA3%"
复制代码
3.学习、理解find和grep(家族)命令
编制两个个性化的文件搜索工具。
#!/bin/bash
echo "个性化文件搜索工具:"
echo "1:grep搜索工具"
echo "2:find搜索工具"
echo "选择想要使用的工具[1|2]:"
read CHOICE
if [ "$CHOICE" == "1" ] #选择grep
then
echo "自定义查找"
echo "请输入查找目录:"
read mulu
ls $mulu > mulu.txt
echo "1:查找以匹配模式开头的文件"
echo "2:查找不包含匹配模式的文件"
echo "3:查找以匹配模式结尾并且长度固定的文件"
read CHOICE1
case $CHOICE1 in
1)echo "查找以匹配模式开头的文件"
read scanf
grep -E ^$scanf mulu.txt
;;
2)echo "查找不包含匹配模式的文件"
read scanf
grep -Ev $scanf mulu.txt
;;
3)echo "查找以匹配模式结尾并且长度固定的文件"
read scanf
echo "请输入长度"
read length
readlength=$(($length-`echo ${#scanf}`))
grep -xE [[:alnum:]]\{$readlength\}$scanf mulu.txt
;;
*)
esac
else #选择find
echo "自定义查找"
echo "请输入查找目录:"
read mulu2
echo "1:查找文件大小大于给定下限的文件"
echo "2:查找给定时间内修改过的文件"
echo "3:查找给定文件后缀的文件"
read CHOICE2
case $CHOICE2 in
1)echo "请输入文件大小下限值(k)"
read size
find $mulu2 -size +$size
;;
2)echo "请输入时间(day)"
read time
find $mulu2 -mtime +$time
;;
3)echo "请输入文件后缀"
read houzhui
find $mulu2 -name *.$houzhui
;;
*)
esac
fi
read DD
复制代码