《Linux操作系统》
课程设计说明书
题目:Shell编程—用户信息管理专业:
班级:
学号:
姓名:
指导老师:
2012年06月08日
一.课程设计目的
《Linux操作系统》课程设计是网络工程专业的集中实践性环节之一,是学习完《linux 操作系统》课程后进行的一次全面的综合练习。其目的在于加深对linux操作系统的系统管理各方面技术的掌握,使学生更好地把握linux操作系统的基础命令、shell脚本技术以及各种基础服务器的配置和基本应用。类UNIX操作系统在网络环境及手持设备环境下使用极为流行,几乎所有的网络服务器都是运行在类UNIX系统之上;基于类UNIX裁剪版本的手持设备也在市场中占有极大的比重,因此,对于网络工程专业掌握类UNIX操作系统的基本使用方法是相当重要的。而Linux就是类UNIX中最为流行的一个分支,鉴于Linux 的开源和Linux开发群的活跃特性,Linux都是高等院校计算机类专业必开设的课程。而Linux操作系统课程设计能够更好的加强学生在课程学习中各种知识的综合应用能力和实践经验。
二.课程设计内容
在主Shell脚本文件里(必须以 menu 命名)要有一个多操作选项的菜单以便用户从中选择。在不同任务的中,这些操作能自动实现以下功能:
1)在屏幕上显示当前所有用户的记录
2)在屏幕上显示当前所有用户(经过格式化和排序的)的记录
3)只在屏幕上显示用户名和用户ID
4)只在屏幕上显示(经过格式化和排序的)用户名和用户ID
5)查询并显示特定用户的记录
6)往passwd文件里增加新的用户记录
7)从passwd文件里删除某个用户记录
在目录下有四个文件分别为menu,passwd,add,delete
注:
●passwd是自建数据文件,而不是/etc/passwd这个文件,切记。
●menu、add和delete是shell脚本文件。
三.课程设计需要知识的基本原理及功能简介
变量定义、变量使用、循环控制结构、条件选择结构、用户交互、文件读写、文本内容分析以及linux重要命令的使用等。程序要包括四个文件,即menu,add,delete,passwd 四个文件。passwd文件是用来保存用户信息;menu文件是主菜单,要求运行的时候能显示一个菜单供用户选择;add文件是用来增加信息;delete文件是用来删除信息。在主Shell 脚本文件里(必须以 menu 命名)要有一个多操作选项的菜单以便用户从中选择。对于任务6和7,需要编写单独的Shell脚本文件(必须分别命名为add和delete)并且在主脚本menu文件中调用这些脚本文件。
四.设计步骤:
1.功能图
2.流程图 2.2.1主菜单
显示当前所有用户的记录
显示当前所有用户(经过格式化和排序的)
的记录的记录
显示用户名和用户ID
显示(经过格式化和排序的)用户名和用户
查询并显示特定用户的记录
添加用户信息
删除用户信息
用户信息主菜单
主菜单
你的选择
功能实现
回车退出
2.2.2 add
模块
2.2.3 delete 模块
3.截图
1) menu 脚本执行后,大概应该呈现为下图所示的情况:
主菜单
是否继续删除
进入delete 界面
输入ID 是否存在 是否删除
进入主菜单
Y
Y
Y
N
N
假如,passwd文件中的内容如下所示:
root:x:0:0:root:/root:/bin/bash
linux:x:500:500:linux:/home/linux:/bin/bash lianmin:x:503:500:lianmin:/home/lianmin:/bin/bash 090510217:x:800:800:liuxy:/home/090510217:/bin/bash liuxianyu:x:801:801:lxy:/home/liuxianyu:/bin/bash
2)选择菜单1时,显示的结果如下图所示:
3)选择菜单2时,显示的结果如下图所示:
4)选择菜单3时,显示的结果如下图所示:
5)选择菜单4时,显示的结果如下图所示:
6)选择菜单5,并输入需要查询的用户名时,显示的结果如下图所示:
7)选择菜单6,显示的结果如下图所示:
完成添加用户后,在调用菜单2应该能够看到新添加用户mycount的信息条目。
8)选择菜单7,通过用户ID来删除用户,显示的结果如下图所示:
9)选择菜单q时,显示的结果如下图所示:
五.源代码
1).源代码主要思路
1. menu主菜单
无效输入
当用户做了选择且所选的操作完成之后,应再次显示主菜单以供用户做下一步选择。在以上等待用户做出选择的菜单中,如果用户偶尔输入了一个代码而不是1、2、3、4、5、6、7、q或Q,就有信息提示“请按回车继续...”。等用户按了回车键之后,再次显示主菜单供用户做其他选择。
查询用户是否存在,先判断是否输入,再判断用户名是否存在。
while true
do
echo "请输入要查询的用户名:"
read answer
echo "$b $answer"
if (test -z "$answer")
then
echo "你还没有输入"
continue
elif
grep -i $answer $dataSource
then
echo " "
break
else
echo "你输入的用户不存在,没有找到 $answer"
break
fi
done ;;
自定义函数,判断passwd文件是否存在,如果文件不存在,会显示警告。CheckDataSourceFileExist()
{
if [ -f $dataSource ]
then
#文件存在
return 0;
else
#文件不存在
clear;
echo -n "警告【$dataSource】不存在!请确认!";
read ;
return 1;
fi
}
2.Add文件
该脚本实现与用户的交互式添加用户信息,包括需要添加用户的:用户名、用户密码、用户ID、组ID、全名、用户家目录、登录shell类型。对于每一项信息需要进行单独的读取和必要验证。此外,我还加入了对于是否继续添加的判断,故添加了isContinue已辅助。
对于用户创建的用户名的判断,先判断用户名是否为空,再对于首字母的判断,最后判断所以字符是不是字母和数字
userName="";
while [ -z $userName ]#判断用户输入一个无效的用户名
do
echo -n "用户名:";
read userName;
if [ -z $userName ]
then
echo "错误!用户名是不能为空的,请重新输入!";
continue;
fi
if [ `expr match $userName "[a-zA-Z][0-9a-zA-Z]*"` -ne `expr length $userName` ]
then
echo "错误!用户名的只能由非数字打头的字符和数字组成,请重新输入!";
userName="";
continue;
fi
done
对于用户名密码的判断,判断密码是否为空,且密码长度必须为6位的大小写字母、数字和控制字符组成,然后判断两次输入的用户名和密码是否一样。
while [ -z $passWord ]
do
echo -n "密码:";
read passWord;
if [ -z $passWord ]
then
echo "错误!密码是不能为空的,请重新输入!";
continue;
fi
if [ `expr length $passWord` -ne 6 ]
then
echo "密码长度为6位,请重新输入!";
passWord="";
continue;
fi
if [ `expr match $passWord "[0-9a-zA-Z]*"` -ne `expr length $passWord` ]
then
echo "密码由大小写字母、数字和控制字符组成,请重新输入!";
passWord="";
continue;
fi
echo -n "请在输入一次密码:";
read passWordAgain;
if [ $passWordAgain != $passWord ]
then
echo "两次输入的密码不一样,请重新输入!";
passWord="";
continue;
fi
done
对于用户UID输入处理,UID为数字,一般非超级用户的ID大等于500,范围为500~60000,且不为空。对于用户组GID处理,一般非超级用户的GID大等于500,范围为500~60000,且不为空。用户的工作目录默认为“/home/用户名”。登录权限有bash,sh,csh,ksh可以供选择。
3.Detele文件
delete脚本通过用户ID,找到passwd文件中对应用户ID的记录,并将其删除。同时要考虑到用户可能误操作,因此要在真正删除用户信息前,进行用户确认,如果用户不确认删除,那么就不能将用户信息记录从passwd中删除。这就需要一个临时文件tempFile进行辅助,将删除后的效果保存于该临时文件中,只有用户确认删除后,再将临时文件tempFile 内容写入到passwd文件。否者保持passwd内容不变。此外,我还加入了对于是否继续删除的判断,故isContinue已做辅助。
2).源代码原码
1.menu主脚本文件代码
#! /bin/bash
dataSource='passwd';
homePath='.';
AddUsers=". Add.sh";
DeleteUsers=". Delete.sh";
#自定义函数,判断passwd文件是否存在
CheckDataSourceFileExist()
{
if [ -f $dataSource ]
then
#文件存在
return 0;
else
#文件不存在
clear;
echo -n "警告【$dataSource】不存在!请确认!";
read ;
return 1;
fi
}
a="你的选择是:"
b="输入关键字是:"
clear
while true
do
CheckDataSourceFileExist;
echo " ==========信息主菜单======================="
echo " 1.打印当前所有记录"
echo " 2.打印当前所有记录(格式化后)"
echo " 3.打印用户名和用户ID"
echo " 4.打印(格式化了的)用户名和用户ID"
echo " 5.查询特定记录"
echo " 6.增加新记录"
echo " 7.删除记录?"
echo " q.---退出"
echo -e " 你的选择是:(等待用户输入)"
echo
read choice
echo "$a $choice"
case $choice in
1) CheckDataSourceFileExist;
awk -F: '{ print $1 OFS $2 OFS $3 OFS $4 OFS $5 OFS $6 OFS $7 }' $dataSource;;
2) CheckDataSourceFileExist;
awk -F: '{ print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7 }' $dataSource | sort;;#此处对于用户名排序,\t用于格式化,下同
3) CheckDataSourceFileExist;
awk -F: '{ print $1 OFS $3 }' $dataSource;;
4) CheckDataSourceFileExist;
awk -F: '{ print $1 "\t" $3 }' $dataSource | sort;;
5) CheckDataSourceFileExist;#查询用户是否存在
while true
do
echo "请输入要查询的用户名:"
read answer
echo "$b $answer"
if (test -z "$answer")
then
echo "你还没有输入"
continue
elif
grep -i $answer $dataSource
then
echo " "
break
else
echo "你输入的用户不存在,没有找到 $answer"
break
fi
done ;;
6)$AddUsers;;#读取Add.sh文件
7)$DeleteUsers;;#读取Delete.sh文件
q)exit;;
Q)exit;;
*)echo "无效的代码";;
esac
echo "请按回车继续... "
read answer
done
2.Add脚本文件代码
#!/bin/sh
isContinue="y";
userName="";
while [ $isContinue = "y" -o $isContinue = "Y" ]
do
echo " 用户信息增加情况";
echo "=================================";
echo "输入新用户的具体情况";
#用户名处理,输入一致到字符串长度不为0为止
userName="";
while [ -z $userName ]#判断用户输入一个无效的用户名
do
echo -n "用户名:";
read userName;
if [ -z $userName ]
then
echo "错误!用户名是不能为空的,请重新输入!";
continue;
fi
if [ `expr match $userName "[a-zA-Z][0-9a-zA-Z]*"` -ne `expr length $userName` ]
then
echo "错误!用户名的只能由非数字打头的字符和数字组成,请重新输入!";
userName="";
continue;
fi
done
#密码处理:1.验空,3.密码长度要6位,由大小写字母、数字和控制字符组成,2.验两次输入的一致性,
passWord="";
passWordAgain="";
while [ -z $passWord ]
do
echo -n "密码:";
read passWord;
if [ -z $passWord ]
then
echo "错误!密码是不能为空的,请重新输入!";
continue;
fi
if [ `expr length $passWord` -ne 6 ]
then
echo "密码长度为6位,请重新输入!";
passWord="";
continue;
fi
if [ `expr match $passWord "[0-9a-zA-Z]*"` -ne `expr length $passWord` ]
then
echo "密码由大小写字母、数字和控制字符组成,请重新输入!";
passWord="";
continue;
fi
echo -n "请在输入一次密码:";
read passWordAgain;
if [ $passWordAgain != $passWord ]
then
echo "两次输入的密码不一样,请重新输入!";
passWord="";
continue;
fi
done
#用户UID输入处理,UID为数字、一般非超级用户的ID大等于500
uID="";
while [ -z $uID ]
do
echo -n "用户ID:";
read uID;
if [ -z $uID ]
then
echo "错误!用户UID是不能为空的,请重新输入!";
continue;
fi
if [ `expr match $uID "[0-9]*"` -ne `expr length $uID` ]
then
echo "错误!用户的UID必须为数字,请重新输入!";
uID="";
continue;
fi
if [ $uID -lt 500 -o $uID -gt 60000 ]
then
echo "错误!一般非超级用户的ID范围为500~60000,请重新输入!";
uID="";
continue;
fi
done
#用户组GID处理
gID="";
while [ -z $gID ]
do
echo -n "Group ID:";
read gID;
if [ -z $gID ]
then
echo "错误!用户GID是不能为空的,请重新输入!";
continue;
fi
if [ `expr match $gID "[0-9]*"` -ne `expr length $gID` ]
then
echo "错误!用户的GID必须为数字,请重新输入!";
gID="";
continue;
fi
if [ $gID -lt 500 -o $gID -gt 60000 ]
then
echo "错误!用户组的ID范围为500~60000,请重新输入!";
gID="";
continue;
fi
done
echo -n "用户全名:";read note;
#bash,sh,csh,ksh
shellVersion="";
while [ -z $shellVersion ]
do
echo -n "登录SHELL(bash,sh,csh,ksh):";
read shellVersion;
if [ $shellVersion != "bash" -a $shellVersion != "sh" -a $shellVersion != "csh" -a $shellVersion != "ksh" ]
then
echo "输入的Shell类型【$shellVersion】不在本系统支持范围内,请重新输入!";
shellVersion="";
fi
done
echo -n "用户工作目录:";
sudo mkdir /home/$userName;
if [ $? -eq 0 ]
then
echo $userName "成功创建!";
fi
userInfo="$userName:$passWord:$uID:$gID:$note:$userName:$shellVersion";
echo $userInfo >> $dataSource;
if [ $? -eq 0 ]
then
echo "$userName用户信息添加成功!";
else
echo "$userName用户信息添加失败!";
fi
echo -n "是否继续添加其他用户??(y/n)";
read isContinue;
done
3.Detele脚本文件代码
#!/bin/sh
isContinue="y";
userName="";
while [ $isContinue = "y" -o $isContinue = "Y" ]
do
while [ $isContinue = "y" -o $isContinue = "Y" ]
do
echo -n "输入用户的名称:";
read userName;
if [ -z "$userName" ]
then
echo "用户名不能为空,请重新输入!";
isContinue="Y";
continue;
fi
CheckDataSourceFileExist;
if [ $? -ne 1 ]
then
deleteUser=$(awk -F ":" '$1 == "'$userName'" { print $0 }' $dataSource);
if [ $deleteUser ]
then
echo "目标帐号确认:" $deleteUser;
echo -n "是否删除该信息??(y/n)";
read isContinue;
if [ -z $isContinue ]
then
isContinue="N";
fi
if [ $isContinue = "y" -o $isContinue = "Y" ]
then
CheckDataSourceFileExist;
if [ $? -ne 1 ]
then
rowID=$(grep -n $deleteUser $dataSource | awk -F ":" '{print $1}');
sed -e "$rowID d" $dataSource > tempFile;
cat tempFile > $dataSource;
rm tempFile;
fi
if [ $? -eq 0 ]
then
echo "删除成功!";
else
echo "系统错误,删除失败!";
fi
isContinue="N";
fi
else
echo "你输入的【$userName】用户不存在!";
isContinue="N";
fi
fi
done
if [ -n "$userName" ]
then
echo -n "是否继续删除其他用户??(y/n)";
read isContinue;
if [ -z $isContinue ]
then
isContinue="N";
fi
fi
done
4.passwd文件
root:x:0:0:root:/root:/bin/bash
linux:x:500:500:linux:/home/linux:/bin/bash
lianmin:x:503:500:lianmin:/home/lianmin:/bin/bash
090510217:x:800:800:liuxy:/home/090510217:/bin/bash
liuxianyu:x:801:801:lxy:/home/liuxianyu:/bin/bash
六.课程设计心得体会:
本次课程设计一共进行了3周,对于期间的设计,我感触颇深。因为开始我对于linux这块的shell脚本编程不大感兴趣。但是由于老师的刻意强调,我开始查找各种资料。在参考网上的资料,以及老师给的资料,对于设计题目有了很大的帮助。但是对于直接修改pash 路径执行shell文件的时候遇到了困难。开始对于格式化显示的理解不够深刻,加上没有排序,最后在同学的帮助下,运用“\t”加上“sort”进行的第二步和第四步。开始设计的时候考虑的不够周全,最后发现应该在执行任意代码时都需要判断passwd文件是否存在。对于add和delete的思路多半参考文献4中的思路,对于用户输入的判断还有不足之处。特别是做删除的时候,开始不知道怎么创建临时文件,经常会删除passwd里的所有文件。但是最后都解决了。本次设计让我体会到,做事情只要能沉下心来,对于不了解的东西,一样可以做的很好。当然,这中间也有多少是同学和指导老师的帮助。对于linux下shell 文件的编写也有了重新的认识。
七.参考资料
[1] ubuntu. Shell编程基础. Ubuntu wiki主站.
https://www.wendangku.net/doc/316820808.html,/ Shell编程基础
[2] ubuntu. Bind9安装设置指南. Ubuntu wiki主站.
https://www.wendangku.net/doc/316820808.html,/ Bind9安装设置指南
[3] W3cschool. PHP 教程. W3C.
https://www.wendangku.net/doc/316820808.html,/php/
[4] Linux shell大作业. 百度文库. 百度.
https://www.wendangku.net/doc/316820808.html,/view/aff36a19964bcf84b9d57bc5.html
[5] 解析LINUX的passwd文件.幽幽灵夜. 2009
https://www.wendangku.net/doc/316820808.html,/data/html/2009-8-5/78085.html