《Linux课程设计》
设计题目: shell 编程实现用户信息管理 专 业: 软件工程 指导教师: 蔡照鹏 王斌斌 班 级: 学 号: 姓 名: 同 组 人:
计算机科学与工程学院
1
前言
Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核.Linux可安装在各种计算机硬件设备中。Linux是一个领先的操作系统,世界上运算最快的10台超级计算机运行的都是Linux操作系统。严格来讲,Linux这个词本身只表示Linux内核,但实际上人们已经习惯了用Linux来形容整个基于Linux内核,并且使用GNU 工程各种工具和数据库的操作系统。Linux得名于天才程序员林纳斯·托瓦兹。 Linux操作系统是UNIX操作系统的一种克隆系统,它诞生于1991 年的10 月5 日(这是第一次正式向外公布的时间)。以后借助于Internet网络,并通过全世界各地计算机爱好者的共同努力,已成为今天世界上使用最多的一种UNIX 类操作系统,并且使用人数还在迅猛增长。 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件.Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。它主要用于基于Intel x86系列CPU的计算机上。这个系统是由全世界各地的成千上万的程序员设计和实现的.其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。
2
目录
一、系统环境 ...................................................................................... 1 1.1硬件环境 ................................................................................ 1 1。2软件环境 ............................................................................. 1 二、设计目的和要求 .......................................................................... 1 三、课程设计内容 .............................................................................. 2 四、总体设计 ...................................................................................... 2 4.1部分功能模块流程图 ........................................................... 2 4。2总体功能模块图 ................................................................ 4 五、详细设计 ...................................................................................... 5 5。1模块功能说明..................................................................... 5 5。2系统中shell主要命令说明 ............................................... 5 六、调试与测试 .................................................................................. 7 6.1调试方法 ................................................................................ 7 6.2测试结果的分析与讨论 ..................................................... 12 七、设计中遇到的问题及解决方法 ............................................... 12 八、源程序清单 ................................................................................ 13 九、总结 ............................................................................................ 21 参考文献 ............................................................................................ 22
3
一、系统环境
1。1硬件环境
CPU:Intel(R) Core(TM)2 Duo CPU E7500 @2。93GHz 内存:2.93 GHz,2.00GB
软件:VC6。0、VMware Workstation、CentOS
1。2软件环境
操作系统:Windows 7、 Linux
编程工具、编程语言: shell编程语言 Shell编程语言简介:
shell 是操作系统的最外层.shell 合并编程语言以控制进程和文件,以及启动和控制其它程序.shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。shell 提供了与操作系统通信的方式.此通信以交互的方式(来自键盘的输入立即操作)或作为一个 shell 脚本执行。shell 脚本是 shell 和操作系统命令的序列,它存储在文件中。
二、设计目的和要求
掌握linux操作系统中shell脚本编程技术中的:变量定义、变量使用、循环控制结构、条件选择结构、用户交互、文件读写、文本内容分析以及linux重要命令的使用等.以验证学生对于shell脚本编程的掌握情况。要求学生能够利用shell脚本编程实现较为基本的功能。
Linux作为多用户、多任务的操作系统,其系统资源是所有用户共享的。对用户的管理是操作系统的重点。LINUX课程设计要用shell编程实现,将理论学习付诸实践.设计一个脚本(shell)程序能实现增加、删除、查找和显示特定用户信息的功能。
1
三、课程设计内容
在主Shell脚本文件里(必须以 menu 命名)要有一个多操作选项的菜单以便用户从中选择。在不同任务的中,这些操作能自动实现以下功能:
1) 在屏幕上显示当前所有用户的记录
2) 在屏幕上显示当前所有用户(经过格式化和排序的)的记录 3) 只在屏幕上显示用户名和用户ID
4) 只在屏幕上显示(经过格式化和排序的)用户名和用户ID 5) 查询并显示特定用户的记录
6) 往passwd文件里增加新的用户记录 7) 从passwd文件里删除某个用户记录
在目录下有四个文件分别为menu,passwd,add,delete其中: menu文件中的程序完成1,2,3,4,5功能;另外写一个add脚本文件和delete脚本文件分别实现选项6和7.当用户做了选择且所选的操作完成之后,可以再次显示主菜单以供用户做下一步选择。用while循环和case条件语句配合来完成此操作。 Q:退出
四、总体设计
4.1部分功能模块流程图
(1)总体流程图
主菜单你的选择功能实现回车退出 图4—1 总体流程图
2
(2)查看指定用户
图4-2 查看指定用户
(3)添加用户
主菜单界面N进入add界面Y是否继续添加输入信息是否有效YY是否保存N进入主菜单
图4-3 添加用户
3
(4)删除用户
主菜单界面N进入delete界面Y是否继续删除输入ID是否存在YY是否删除N进入主菜单
图4-4 删除用户
4。2总体功能模块图 用户信息主菜单 显示 当 前 所有 用 户 的 记录
显示当前所有用户经格式化的显示用户名和用户ID 显示当前所有用户 显示经格式化后的用户名和用查找指定用户信息 添加用户信息删除用户信息
图4-5 总体功能模块图
4
五、详细设计
5.1模块功能说明
shell编程用户信息管理系统中,由passwd文件,add。sh,delete.sh,menu.sh三个shell文件组成。
首先编写passwd文件,在此文件里按照/etc/passwd文件的格式[用户名:密码:用户标志号:组标志号:说明域:用户家目录:用户登录成功后使用的shell程序]写下设置的用户信息。
add.sh是对用户信息进行增加的shell程序,提示用户输入用户名,如果没有输入,则继续提示用户输入用户名,如果用户输入了则验证用户名是否符合用户名的要求,是否以非数字打头的字符和数字组成,如果不符合要求则要求用户重新输入,如果符合要求用户需要继续输入密码,然后验证密码和重新输入密码两次输入密码是否一致,若一致则需要用户继续输入用户UID,组GID,说明域,用户家目录,shell路径,若都成功的话,则把信息重定向追加到passwd文件里.
delete.sh是对用户进行删除操作的shell程序,首先需要用户输入用户需要删除的用户名,然后搜索出此用户名的信息,进行确认即可删除。 最后是menu,sh是用户的主函数,通过输入不同的值完成不同的功能,包括显示用户记录,格式化记录,显示用户名和ID,格式化显示用户名和ID,查询特定用户信息,添加新用户,删除用户。
5.2系统中shell主要命令说明
符号 #!: 用来告诉系统它后面的参数是用来执行该文件的程序。
变量: 在shell编程中,所有的变量都由字符串组成,并且不需要对变量进行声明,直接赋值就可以,应用变量的话,用$+变量名的形式。 管道 (|): 将一个命令的输出作为另外一个命令的输入.
echo :将其命令行参数中的字符串或变量的值写到标准输出设备,在显示器上显示一段文字,一般起到一个提示作用。 echo –n不换行输出
echo —e后加上\\起到转义作用
重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。 < :用于输入重定向
> :写入文件并覆盖旧文件
〉〉 :加到文件的尾部,保留旧文件内容。
test命令:通常用” [ ] \"来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ -f \"somefile\" ] :判断是否是一个文件
[ —n \"$var” ] :判断$var变量是否有值
[ expression —a expression ] :当两边的两个expression 表达式都为真
5
[ —z string ]:string长度是0
[ integer1 -eq integer2 ] :当integer1等于integer2 [ integer1 -ne integer2 ] :当integer1不等于integer2 \"if” 表达式: 如果条件为真则执行then后面的部分: if ....; then .。。.
elif ..。.; then ..。. else 。。。. fi
case 表达式:可以用来匹配一个给定的字符串,而不是数字. case .。。 in
.。。) do something here ;; esac
tr \":” ” \":把冒号换成空格
sort:对制定文件中的行按要求进行排序 sort -k 1 $dataSource;//按第一个域进行排序 expr 命令:对表达式进行运算
expr match $string substring命令在string字符串中匹配substring字符串,然后返回匹配到的substring字符串的长度,若找不到则返回0。 expr length $string 求出字符串的长度
字符串过滤命令grep:字符串搜索与过滤,显示所在行的相关信息. grep -i string1 string2 在string2里查找string1,是大小写无关的搜索
grep -n $deleteUser $dataSource:显示查找含有$deleteUser信息,并且在最前面加上行号。
cat file.txt: 输出文件内容到标准输出设备(屏幕)上 read var: 提示用户输入,并将输入赋值给变量
cut:从文件或标准输入中读取内容,并截取每一行的特定部分,然后将结果送到标准输出。
—d sep:指定sep作为输入文件域分隔符,默认为Tab。
cut不支持用空格隔开的列。cut分隔符只能识别冒号,逗号,句号,tab键等非空格作为分隔符的文件或命令执行结果。
cut -d “:\" -f 1,3 /etc/passwd:用冒号为分隔符,输出/etc/passwd文件的第1,3列。
sed:是流编辑器,对它的输入流进行按指定格式的转换。是一个基本的查找替换程序,可以从标准输入读入文本,并将结果输出到标准输出(屏幕)。 sed的操作对象:普通文件,数据流,一个命令的执行结果。 sed -n ‘2p’ student。txt:输出student.txt文件中的第二行
sed —e ”$rowID d\" $dataSource:删除含有$rowID的这一行信息 awk:字符串列截取功能.默认分隔符为白空格。可以用-F指定分隔符. 语法:awk ‘条件{动作}’ file
awk ‘{printf $2 “\” $6}’ student。txt:输出student。txt的第2列和第6列。
6
六、调试与测试
6.1调试方法
1、正常输入
shell程序在/root/linlin/1下
系统主界面:
7
1、显示当前所有记录
2、格式化显示当前所有用户信息:
3、显示用户名和用户ID
8
4、格式化显示用户名和ID
5、查询特定用户信息:
6、添加新用户
9
7、删除用户
10
8、退出
2、特殊输入
1、如果输入的非1~7或Q
2、如果搜索的用户不存在,提示出错信息
11
3、如果删除的用户不存在,提示出错信息
6。2测试结果的分析与讨论
在测试中首先要测试各功能是否能够正常执行,是否可以正常显示系统中用户信息,是否可以格式化系统中所有用户信息,显示和格式化用户名和ID,查询特定用户信息。若输入的选项系统中不存在,也会提示用户此选项不是系统提供的功能,如果在passwd文件中没有所要查询的用户的信息,那么会提示此查找的用户信息不存在。删除用户的时候,删除的用户如果不存在,也会提示此用户不存在。
七、设计中遇到的问题及解决方法
1、开始不太明白shell编程的语法,例如expr的用法,expr match是从字符串的开始匹配,若字符串开始就不匹配,即使中间可以匹配,仍然返回0。 3、经过对文件测试才知道grep -n $deleteUser $dataSource 此句是输入要查找的含有$deleteUser的信息,并且在总的信息前会有查找信息在原来文件中的行号。
4、sed —e \"$rowID d\" $dataSource 〉 tempFile; 此句中d表示删除$rowID行的信息,并且把$dataSource中删除$rowID后的信息新建的方式重定向输出到tempFile文件中。
2、awk -F ”:\" ’$1 == ”'$userName’\" { print $0 }' $dataSource;此句中的特殊变量$0用于存储整条记录的内容,而$1表示每条记录的第一个域。
12
八、源程序清单
1)Menu.sh文件
1#! /bin/bash
dataSource='passwd’; addUsers=\"./add.sh”;
deleteUsers=”。/delete。sh”;CheckDataSourceFileExist() {
if [ -f2 $dataSource ] then #文件存在 return 0; else
#文件不存在
1
#!程序解释器路径 2
-f file判断文件存在
13
(
fi }
clear;
echo -n \"警告 【$dataSource】 不存在!请确认!\"; read ; return 1;
choice=\"F”;
while [ $choice != ”Q” -a1 $choice != \"q” ] do
CheckDataSourceFileExist; if [ $?2 —ne3 1 ] then
clear;
echo \" 用户信息管理主菜单”;
echo ”===========================================================\";
1
echo \" 1.显示当前所有记录\";
echo \" 2。格式化显示当前所有记录\"; echo \" 3.显示用户名和用户ID”; echo ” 4.格式化显示用户名和ID\"; echo ” 5。查询特定用户信息\"; echo \" 6.添加新用户”; echo ” 7。删除用户\"; echo ” Q。退出”; echo —n ”你的选择:\"; read choice;
if [ -z4 $choice ] then
choice=\"empty”; fi
clear;
if [ $choice = ”empty\" ]; then
echo \"选项尚未选择!\"; else
case $choice in
1) CheckDataSourceFileExist; if [ $? —ne 1 ]
当两边的两个表达式都为真时 2
$?代表上一个命令执行后的推出状态,0是成功,非0失败 3
-ne是不等于
4
-z判断长度是0
14
then
echo \"当前的所有的用户信息如下所示:”;
echo ”用户名 密码 ID GID 说明 工作目录 登录Shell\" cat $dataSource | tr1 \":\" \" \" | more; fi;;
2) CheckDataSourceFileExist; if [ $? -ne 1 ] then
echo \"当前的所有的用户信息如下所示:\"; echo -e2 ”用户名\密码\ID\GID\说明\工作目录\登录Shell\" sort —k 1 $dataSource | awk -F \":\" '{print $1 \"\\" $2 ”\\" $3 \"\” $4 ”\” $5 ”\” $6 ”\\" $7 ”\”}’ | more; fi;;
3) CheckDataSourceFileExist;
if [ $? —ne 1 ] then
more;
echo ”当前的所有的用户的用户名和用户ID如下所示:\"; echo —e \"用户名,ID\";
awk -F3 ”:\" ’{print $1 \$3}’ $dataSource |
fi;; CheckDataSourceFileExist; if [ $? -ne 1 ] then
4)
echo ”当前的所有的用户的用户名和用户ID如下所示:”;
echo -e ”用户名 \ ID”;
awk -F ”:” ’{print $1 ”\ \" $3}’ $dataSource | more;
fi;;
5) CheckDataSourceFileExist; if [ $? -ne 1 ] then
keyWords=\"”;
while [ -z $keyWords ] do
echo —n ”输入搜索关键词:”; read keyWords; if [ —z $keyWords ]
1
tr 用空格替换: 2
-e后加上\\起到转义作用
3
-F以后面的东西作为分隔符
15
then
echo \"搜索关键词不能为空,请重新输入”; fi done
CheckDataSourceFileExist; if [ $? —ne 1 ] then
grep —i1 $keyWords $dataSource;
if [ $? -eq 1 ] then
echo ”很遗憾,【$dataSource】文件中,并不存在与 $keyWords 一致的信息.”; fi fi fi;;
fi
6) $addUsers;; 7) $deleteUsers;;
Q) printf ”程序已经退出。”;; q) printf ”程序已经退出。”;; *) echo $choice ”:此选项不是默认提供的功能。请确认”;; esac
echo —n \"确认??\"; read ; fi Done
#! /bin/bash
dataSource='passwd';
(2)add。sh文件
clear;
isContinue=”y”; userName=””;
while [ $isContinue = ”y\" -o2 $isContinue = ”Y\" ] do
userName=\"”;
while [ -z $userName ] do
echo -n \"用户名:\"; read userName; if [ —z $userName ] then
1 Grep –i大小写无关的搜索
2
# 表达式1或者表达式2为true
16
echo \"错误!用户名是不能为空的,请重新输入!”; continue; fi
if [ `expr match $userName \"[a-zA-Z][0-9a—zA—Z]*”` —ne `expr length $userName` ] then
echo ”错误!用户名的只能由非数字打头的字符和数字组成,请重新输入!”; userName=\"\"; continue; fi done
passWord=”\";
passWordAgain=\"\";
while [ —z $passWord ] do
echo —n ”密码:\";
read passWord; if [ —z $passWord ] then
echo ”错误!密码是不能为空的,请重新输入!”; continue; fi
if [ `expr length $passWord` —ne 6 ] then fi
echo ”密码长度为6位,请重新输入!”; passWord=\"\"; continue;
if [ `expr match1 $passWord ”[0—9a—zA—Z]*\"` -ne `expr length $passWord` ] then
1
fi echo \"密码由大小写字母、数字和控制字符组成,请重新输入!”; passWord=\"”; continue;
echo -n \"请在输入一次密码:”; read passWordAgain;
if [ $passWordAgain != $passWord ] then
echo \"两次输入的密码不一样,请重新输入!”; passWord=\"”;
continue; fi
expr match $string substring命令在string字符串中匹配substring字符串,然后返回匹配到的substring字符串的长度,若找不到则返回0
17
done
#用户UID输入处理,UID为数字、一般非超级用户的ID大等于500 uID=””;
while [ —z $uID ] do
echo —n \"用户UID:”; read uID; if [ —z $uID ] then
echo ”错误!用户UID是不能为空的,请重新输入!”; continue; fi
if [ `expr match $uID ”[0—9]*\"` -ne `expr length1 $uID` ] then fi
echo ”错误!用户的UID必须为数字,请重新输入!\"; uID=””; continue;
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 \"用户组GID:”; 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;
1
expr length $string 求出字符串的长度
18
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 ”用户工作目录:”; 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
#! /bin/bash dataSource=’passwd'; 。./menu。sh;
(3)delete.sh文件
19
clear;
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=$(grep1 —n $deleteUser $dataSource | awk —F \":” '{print $1}’);
sed2 -e ”$rowID d\" $dataSource 〉 tempFile;
1
grep -n $deleteUser $dataSource:显示查找含有$deleteUser信息,并且在最前面加上行号。
2 sed:是流编辑器,对它的输入流进行按指定格式的转换。是一个基本的查找替换程序,可以从标准输入读入文本,并将结果输出到标准输出(屏幕)。 sed的操作对象:普通文件,数据流,一个命令的执行结果。 sed -e \"$rowID d\" $dataSource:删除含有$rowID的这一行信息
20
cat1 tempFile 〉 $dataSource; rm tempFile; fi if [ $? —eq 0 ] then
echo \"记录删除!”; else
echo \"系统错误,删除失败!\"; fi
isContinue=”N”; fi else
echo \"你输入的 【$userID】 用户不存在!\"; isContinue=\"N”; fi fi done
if [ -n2 \"$userName\" ] then
echo —n ”是否继续删除其他用户??(y/n)\"; read isContinue; if [ -z $isContinue ] then
isContinue=”N”; fi
fi Done
九、总结
通过此次shell编程实现用户信息管理课程设计,加深了自己对shell编程的应用,首先了解了正则表达式的使用,然后了解流编辑工具sed,列截取命令awk,列切割命令cut,两者都是列截取命令,但其参数和用法不同,awk用法为:awk ‘条件{动作}’,并且域间分隔符参数为—F,默认为白空格,而cut以参数—d来设置分隔符,默认为tab键,并且不支持空格为分隔符。
此次shell编程实现用户信息管理课程设计,更加深刻的理解了用户,组的管理及/etc/passwd文件内容格式的理解.在程序中,还用到了tar命令解压缩文件,分屏显示文件内容more,vi编辑器的使用,对linux系统中的目录结构和shell的基本功能和概念有了进一步的理解和掌握。 1
查看文件并把查看的结果重定向输出到passwd文件。 2 -n 非0
21
在shell编程中也用到了IO重定向(〈 输入重定向;〉 用于新建或覆盖方式重定向输出;>> 用于追加方式重定向输出),单引号(单引号代表普通字符),双引号的使用(可用户变量替换,命令替换,也可当做普通字符),反单引号的使用(命令替换),变量的使用(定义变量不需声明,但是需要用$来取值),还用到grep进行对特定值的搜索,还有if-then—if,case结构,以及shell中test条件测试的使用。从而加深了自己对shell更进一步的了解,增加了对linux的兴趣。
代码不是很完善,有些功能没有实现(修改用户信息;UID不需用户输入,可以自动生成(可以每生成一个用户,UID自动加1);不能添加重复的用户名和UID,这个功能需要用到列切割和grep搜索)
参考文献
1。 邵国金 《Linux 操作系统(第2版)》 电子工业出版社,2014
2。 汤小丹 《计算机操作系统(第三版)》 西安电子科技大学出版社 2012
22
因篇幅问题不能全部显示,请点此查看更多更全内容