Linuxc编程作业_第1页
Linuxc编程作业_第2页
Linuxc编程作业_第3页
Linuxc编程作业_第4页
Linuxc编程作业_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在此处键入文档的摘要。摘要通常是对文档内容的简短总结。在此处键入文档的摘要。摘要通常是对文档内容的简短总结。目录1.第一次上机作业11.1调试运行CD唱片应用程序。11.2编写shell脚本,求1到100的和。111.3编写shell脚本,从键盘输入两个数,求这两个数的和。121.4等待特定用户登录,每30秒确认一次。131.5找出系统中当前消耗磁盘容量最大的前10个用户,并向他们发送警告邮件。141.6查找输入文件的路径。152. 第二次上机作业162.1定制自己的ls命令。提供至少三种带参数的执行方式;162.2调试编译串行口通信程序p6.5.c;253. 第三次上机作业333.1创建一个

2、系统监听守护进程,一旦接收到其他进程发来的信号,马上给出报告;333.2分别利用本地socket套接字和INTENET套接字实现进程间文件传输;364. 总结431.第一次上机作业1.1调试运行CD唱片应用程序。 shell源代码分析:# 设置全局变量 设置ctrl+c组合键中断处理,确保用户中断脚本程序是删除临时文件menu_choice=""current_cd=""title_file="title.cdb"tracks_file="tracks.cdb"temp_file=/tmp/cdb.$ # $当前进

3、程号trap 'rm -f $temp_file' EXIT 设置的全局变量,包括标题文件,曲目文件和一个临时文件。#定义简单工具函数get_return() # 函数和花括号之间留有空格显得更整齐些 echo -e "Press return c" # -e 用在字符串中有转义字符的情况,#c表示取消行末换行符 read x return 0get_confirm() # 两个函数间留有空格 echo -e "Are you sure? c" while true do read x case "$x" in y |

4、 yes | Y | Yes | YES ) return 0; n |no | N | No |NO ) echo echo "Cancelled" return 1; *) echo "Please enter yes or no" esac done 为了避免在几个地方反复编写同样的代码,在这里设置了get_return和ger_confirm两个工具函数,并且在最开始位置定义,以确保后面的函数均可找到它们的定义。# 主菜单set_menu_choiceset_menu_choice() Clear #清屏 echo "Optons :-

5、" echo # 单个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"

6、 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 和 insert_track 向数据库文件添加数据;#add_record_tracks 添加曲目信息insert_title(

7、) echo $* >> $title_file # >>以追加的方式重定向输出 returninsert_track() echo $* >> $tracks_file returnadd_record_tracks() echo "Enter track information for this CD" echo "When no more tracks enter q" cdtrack=1 cdttitle="" while "$cdttitle" != "q&q

8、uot; do echo -e "Track $cdtrack,track title? c" read tmp cdttitle=$tmp%,* # 从尾部删除与,最长的匹配 用来截取字符串 if "$tmp" != "$cdttitle" ;then echo "Sorry, no commas allowed" continue fi if -n "$cdttitle" ; then # -n 用来检查是否为空字符串 if "$cdttitle" != "q&

9、quot; ; then insert_track $cdcatnum,$cdtrack,$cdttitle fi else cdtrack=$(cdtrack-1) fi cdtrack=$(cdtrack+1)done 在这里,insert_title 和 insert_track 向数据库文件添加数据,add_record_tracks函数会用到上面两个小函数。这个函数使用模式匹配来确保用户未输入逗号(因为逗号作为数据字段之间的分隔符),使用算数操作在用户输入曲目是递增当前曲目的编号。# add_records 函数用于输入新CD唱片的标题信息add_records() # Prompt

10、 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

11、 to enter the information echo About to add new entry echo "$cdcatnum $cdtitle $cdtype $cdac" # If confirmed the append it to the tiltles file if get_confirm ;then insert_title $cdcatnum,$cdtitle,$cdtype,$cdac add_record_tracks else remove_records fi returnadd_records函数用于输入新的CD唱片的标题信息。实现了添

12、加功能。# find_cd 用grep命令在CD唱片标题文件中查找CD唱片的有关资料。#用$wc -l $temp_file输出中以空格分隔被统计文件中的行数单词数和# 字符数;# 用set命令把shell参变量设置成wc输出的结果;#IFS(内部字符分割符)设置为一个逗号,读取以逗号分隔的数据字段,也可用cut。find_cd() if "$1" = "n" ;then # 需要含参的调用形式 asklist=n else asklist=y fi cdcatnum="" echo -e "Enter a string t

13、o search for in the CD titles c" read searchstr if "$searchstr" = "" ;then return 0 fi grep "$searchstr" $title_file > $temp_file# grep 只把带“$searchstr”字符串的行输出到$temp_file中 set $(wc -l $temp_file) # 用wc命令统计行数单词数和字符数 并将其set到环境变量中去 linesfound=$1 # 取第一个环境变量 case &quo

14、t;$linesfound" in 0) echo "Sorry,nothing found" get_return return 0 ; 1) ; 2) echo "Sorry,not unique." echo "Found the following" cat $temp_file # cat命令用于读取并输出普通文件 get_return return 0 esac IFS="," # 将分割符设置为逗号 read cdcatnum cdtitle cdtype cdac < $temp_f

15、ile # 之前已经在$temp_file中用逗号分别存储几个变量 IFS=" " if -z "$cdcatnum" ;then # -z表示字符串为空则为真 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 e

16、cho 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 find_cd函数实现查找功能,使用grep命令在CD唱片标题文件中查找CD唱片的有关资料。# update_cd函数用于重新输入CD唱片资料。#想要搜索的行是以$cdcatum开头(通过标志)并且#其后跟着一个

17、逗号,因此把$cdcatum变量的扩# 展放在一对花括号里(把参数的值替换进了字#符串)。用花括号将要执行的多个语句组成一个语句块。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

18、 for $cdtitle" get_confirm && grep -v "$cdcatnum," $tracks_file > $temp_file# (>清空原有的)grep -v 用于删除文件中的字符串 表示开头 mv $temp_file $tracks_file echo add_record_tracks fi return# count_cds函数 用于快速统计CD唱片的个数和曲目总数count_cds() set $(wc -l $title_file) num_titles=$1 set $(wc -l $track

19、s_file) num_tracks=$1 echo found $num_titles CDs, with a total of $num_tracks tracks get_return return# remove_records函数用于从数据库文件中删除数据项,#grep -v 命令删除说有匹配的字符串,必须使用一个临时文件来完成# 否则grep -v "$cdcatnum," $title_file > $title_file# 会在grep命令执行之前将#title_file重定向为空文件remove_records() if -z "$cdca

20、tnum" ; then 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 mv $temp_file $title_file # 将a重命名为b grep -v "$cdcatnum," $tr

21、acks_file > $temp_file mv $temp_file $tracks_file cdcatnum="" echo Entry removed get_return fi return# list_tracks函数 通过grep找出你想要的行 通过cut命令访问你想要的字段,#通过more命令 提供按页输出(如果用c语言大概需要20多行)list_tracks() if "$cdcatnum" = "" ; then echo no CD selecter yet return else grep "

22、$cdcatnum," $tracks_file > $temp_file num_tracks=$(wc -l $temp_file) if "num_tracks" = "0" ; then echo no tracks found $cdtitle else echo echo "$cdtitle : -" echo cut -f 2- -d , $temp_file # -f表示字段 2-表示从第二个到结束 #-d用来定义以后面的逗号为分割符 整体表示从没行的第二 # 个参数开始截取 echo | $PAGER

23、:-more # 通过管道分页显示 fi fi get_return return# 主程序 如果用户选择了退出程序就先删除临时文件,在线是结束信息,#最后成功退出(退出码#0)rm -f $temp_fileif ! -f $title_file ; then touch $title_file # 如果没有该文件则创建fiif ! -f $tracks_file ; then touch $tracks_filefi# Now the application properclearechoechoecho "Mini CD manager"sleep 1quit=nwh

24、ile "$quit" != y ;do set_menu_choice case "$menu_choice" in a) add_records; r) remove_records; f) find_cd y; # 注意带参数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" esacdone# Tidy

25、up and leaverm -f $temp_fileecho "Finished"exit 0运行结果:1)运行shell命令2)最开始进入的菜单界面3)选择“a”进行添加操作4)完成添加后的菜单界面,注意多了“l”,“r”,“u”功能5)选择“f”功能6)选择“c”计数功能7) 选择“l”,列出tracks on Tyler8)选择“u”,更新tracks on Tyler9)更新后的tracks on Tyler10)删除Tyler11)删除Tyler后的菜单界面12)选择“q”退出1.2编写shell脚本,求1到100的和。Shell代码:#!/bin/shsta

26、rt=1end=100sum=0while($start<=$end)do sum=$($start+$sum) start=$($start+1)doneecho "sum from 1 to 100 equeal to $sum "exit 0 用while循环来实现从1到100的累加。运行结果:1)从1到100的累加的结果如图所示,为50501.3编写shell脚本,从键盘输入两个数,求这两个数的和。Shell源代码:#!/bin/shread -p " please enter a number a=" aread -p " pl

27、ease enter another number b=" bsum=$($a+$b)echo "sum of a and b equeal to " $sumexit 0首先,输入两个变量,用sum保存相加结果,再输出结果。运行结果:1)运行shell,a=123,b=3456,结果为35792)当输入非数字时,该输入被视为01.4等待特定用户登录,每30秒确认一次。Shell源代码:#!/bin/bashread -p " please put in the user:" useruntil who | grep "$user&q

28、uot; > /dev/nulldo echo "try it again after 30s!" sleep 30 read -p " please put in the user:" userdoneecho "-$user has just logged in -"exit 0who | grep “$user”>/dev/null,使用who得到所有用户,再使用管道传输结果,grep显示与$user字符串匹配的用户。使用>/dev/null,将stdout输入到linux的无底洞。这里使用的until.do循

29、环语句,验证失败时,等待时间为30秒。运行结果:1)运行成功的结果:2)当输入的用户验证失败时,等待30秒,再试。1.5找出系统中当前消耗磁盘容量最大的前10个用户,并向他们发送警告邮件。Shell源代码:#!/bin/sh(du -s /home/*|sort -nr |sed 10q)>program4.txtecho "The Rusults:" cat program4.txt#取具有文件名的那一列存到d.txt文档中awk -F"/home/" 'print$2' program4.txt >program4_.tx

30、ttag=1#取文档的某一行username=$(head -$tag program4_.txt|tail -1)while ($tag<11) doecho $username#给查找的用户发送警告邮件 echo "Clear up your disk!" | mail -s "warning!" $usernameecho succefully send an e_mail to $username tag=$($tag+1) username=$(head -tag d.txt|tail -1) doneexit 0运行结果:1) 在hom

31、e目录下的用户目录2) 运行结果3) 运行后的program.txt和program4_.txt 1.6查找输入文件的路径。Shell源代码:#!/bin/bashwhile(1)do read -p "please put in the filename:" filename find / -name $filename echodoneexit 0此处使用find命令从根目录开始查找文件。注意:在这里使用主用户来执行程序的,因为许多文件涉及到权限问题。运行结果:1)当输入tylertang时,查找的结果有多条路径;当输入ctrl+c时,跳出循环,结束输入。2. 第二次上

32、机作业2.1定制自己的ls命令。提供至少三种带参数的执行方式;源代码分析:/所用到的头文件。#include <stdio.h>#include <errno.h>#include <sys/stat.h>#include <unistd.h>#include <time.h>#include <pwd.h>#include <grp.h>#include <dirent.h>#include <string.h>#include <stdlib.h>/所用到的变量定义,以及

33、函数声明。定义了链表结构体。int aflag = 0;int lflag = 0;typedef char * datatype;typedef struct _node_ char data256; struct _node_ *next;linknode,*linklist;void Display_file(char *path,char *name); /打印文件的信息void Mode(struct stat buf); /查看文件的各种属性void SeleFi(struct stat buf); /打印文件的类型void Max(struct stat buf); /void

34、Time(struct stat buf); /打印修改文件的时间void GetUID(struct stat buf); /获得UID并打印void GetGID(struct stat buf); /获得GID并打印void Display_Dir(linklist list,char *name); /打印目录void ifDir(linklist list,char *path); /判断是否是目录void getflag(int argc,char *argv,int *aflag,int *lflag); /获得-a或-l的参数void GetName(linklist list

35、,char *name); /获得目录中所有文件名 /创建空的linklist链表函数linklist CreateEmptyLinklist() linklist h=(linklist)malloc(sizeof(linknode);/动态申请空间 h->next=NULL; return h;/清空linklist链表函数int EmptyLinklist(linklist h) return (NULL=h->next);/返回链表结点数int LengthLinklist(linklist h) int i=-1; while(h->next!=NULL) i+;

36、h=h->next; return i;/使指针指到链表尾void VisitLinklist(linklist h) h=h->next; while(h!=NULL) / printf("%dn",h->data); Display_file(h->data,h->data); h=h->next; return ;/将x信息创建结点插入到比它大或相等的第一个结点后面void InsertLinklist_2(linklist h,datatype x) while(h->next!=NULL)&&(strcmp

37、(h->next->data,x) < 0) h=h->next; linklist new=(linklist)malloc(sizeof(linknode); strcpy(new->data,x); new->next=h->next; h->next=new; return ;/删除结点信息为x的结点void DeleteLinklist_2(linklist h,datatype x) linklist p; p=h->next; while(p!=NULL) if(p->data=x) h->next=p->n

38、ext; free(p); h=h->next; p=p->next; /带参数的主函数int main(int argc,char *argv) struct stat buf;/使用stat类型的结构体 int ch; int i; linklist list = CreateEmptyLinklist();/创建list链表 getflag(argc,argv,&aflag,&lflag);/得到flag值for ( i = optind ; i < argc ; i+ ) /下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 if

39、Dir(list,argvi);/判断是否为目录 if (optind = argc) Display_Dir(list,"."); VisitLinklist(list); printf("n"); return 0;/打印文件的类型void SeleFi(struct stat buf) if ( S_ISREG(buf.st_mode) ) printf("-"); if ( S_ISDIR(buf.st_mode) ) printf("d"); if ( S_ISCHR(buf.st_mode) ) pri

40、ntf("c"); if ( S_ISBLK(buf.st_mode) ) printf("b"); if ( S_ISFIFO(buf.st_mode) ) printf("p"); if ( S_ISLNK(buf.st_mode) ) printf("l"); if ( S_ISSOCK(buf.st_mode) ) printf("s"); /打印文件的权限void Mode(struct stat buf) if ( (buf.st_mode)&S_IRUSR ) printf

41、("r"); else printf("-"); if ( (buf.st_mode)&S_IWUSR ) printf("w"); else printf("-"); if ( (buf.st_mode)&S_IXUSR ) printf("x"); else printf("-"); if ( (buf.st_mode)&S_IRGRP ) printf("r"); else printf("-"); if

42、( (buf.st_mode)&S_IWGRP ) printf("w"); else printf("-"); if ( (buf.st_mode)&S_IXGRP ) printf("x"); else printf("-"); if ( (buf.st_mode)&S_IROTH ) printf("r"); else printf("-"); if ( (buf.st_mode)&S_IWOTH ) printf("w&quo

43、t;); else printf("-"); if ( (buf.st_mode)&S_IXOTH ) printf("x"); else printf("-"); printf(" ");/打印buf的文件字节数void Max(struct stat buf) printf("%8ld",buf.st_size); printf(" ");/打印文件创建的时间void Time(struct stat buf) struct tm *tp; tp = localt

44、ime(&(buf.st_ctime); printf("%2d-%2d-%2d %2d:%2d",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min); printf(" ");/得到文件所有者void GetUID(struct stat buf) struct passwd *p; p = getpwuid(buf.st_uid); printf("%3s ",p->pw_name);/得到文件组的信息voi

45、d GetGID(struct stat buf) struct group *g; g = getgrgid(buf.st_gid); printf("%3s ",g->gr_name);/根据路径,文件名,打印出文件信息void Display_file(char *path,char *name) struct stat buf; if ( stat(path,&buf) = -1 ) perror("ls:"); return ; if ( lflag = 1 ) SeleFi(buf); Mode(buf); printf(&qu

46、ot;%3d ",buf.st_nlink); GetUID(buf); GetGID(buf); Max(buf); Time(buf); printf("%sn",name); return ; printf("%s ",name);/根据链表,目录名,列出目录信息void Display_Dir(linklist list,char * dirname) DIR *mydir; struct dirent *dir; char path256; if ( (mydir = opendir(dirname) = NULL ) perror(

47、"DIR:"); return ; printf("%s :n",dirname); while ( (dir = readdir(mydir) != NULL ) if ( dir->d_name0= '.' ) if ( aflag = 0 ) continue; sprintf(path,"%s/%s",dirname,dir->d_name);/ Display_file(path,dir->d_name); GetName(list,dir->d_name); closedir(myd

48、ir);/根据链表信息,路径判断是否为目录,并输出信息void ifDir(linklist list,char *path) struct stat buf; if ( stat(path,&buf) < 0 ) perror("path:"); if ( S_ISDIR(buf.st_mode) ) Display_Dir(list,path); else / Display_file(path,path); GetName(list,path); /根据主函数的参数,得到flag的值void getflag(int argc,char *argv,int

49、 *aflag,int *lflag)int ch;/getopt被用来解析命令行选项参数。就不用自己写东东处理argv了。 while ( (ch = getopt(argc,argv,"la") != EOF ) switch (ch) case 'a': *aflag = 1; break; case 'l': *lflag = 1; break; default: printf("Wrong option !n"); break; /将name插入到链表void GetName(linklist list,char

50、 *name) InsertLinklist_2(list,name); 其中用到的stat结构体,它在头文件#include <sys/stat.h>中,其结构体原型为:struct stat mode_t st_mode; /文件对应的模式,文件,目录等 ino_t st_ino; /inode节点号 dev_t st_dev; /设备号码 dev_t st_rdev; /特殊设备号码 nlink_t st_nlink; /文件的连接数 uid_t st_uid; /文件所有者 gid_t st_gid; /文件所有者对应的组 off_t st_size; /普通文件,对应的文件字节数 time_t st_atime; /文件最后被访问的时间 time_t st_mtime; /文件内容最后被修改的时间 time_t st_ctime; /文件状态改变时间 b

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论