操作系统实验报告shell程序.docx
- 文档编号:8861899
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:22
- 大小:65.06KB
操作系统实验报告shell程序.docx
《操作系统实验报告shell程序.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告shell程序.docx(22页珍藏版)》请在冰豆网上搜索。
操作系统实验报告shell程序
操作系统实习报告日期:
实习题目:
shell程序
完成人
姓名:
组号:
学号
实习内容简要描述
本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。
实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。
ysh程序应当具有如下一些重要的特征:
能够执行外部程序命令,命令可以带参数。
能够执行fg、bg、cd、history、exit等内部命令。
使用管道和输入输出重定向。
支持前后台作业,提供作业控制功能,包括打印作业的清单,改变
当前运行作业的前台/后台状态,以及控制作业的挂起、中止和继续
运行。
除此之外,在这个实验中还须做到:
使用make工具建立工程。
使用调试器gdb来调试程序。
提供清晰、详细的设计文档和解决方案。
主要代码结构
(附注释)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"ysh.h"
#defineNO_PIPE-1
#defineFD_READ0
#defineFD_WRITE1
intis_founded(char*cmd)
{
intk=0;
while(envpath[k]!
=NULL){strcpy(buf,envpath[k]);
strcat(buf,cmd);
if(access(buf,F_OK)==0){return1;
}k++;
}
return0;
}
voidgetenviron(intn,char*s)
{inti=0,j=0,k=0;
charc;
charbuff[80];
char*p;
while((c=s[i])!
='='){buff[i++]=c;
}buff[i++]='\0';
if(strcmp(buff,"PATH")==0){
while(s[i]!
='\0'){if(s[i]==':
'){
buff[j++]='/';
buff[j]='\0';
p=(char*)malloc(strlen(buff)+1);
strcpy(p,buff);
envpath[k++]=p;
envpath[k]=NULL;
j=0;
i++;
}else{
buff[j]=s[i];
j++;
i++;
}
}
}else
fprintf(stderr,"Nomatch");
}
intgetline(intfd,char*buf)
{inti=0;
charc;
while(read(fd,&c,1)){
buf[i++]=c;
if(c=='\n'){
buf[i-1]='\0';
returni;
}
}returni;
}
voidinit_environ()
{
intfd,n;
charbuf[80];
if((fd=open("ysh_profile",O_RDONLY,660))==-1){
printf("initenvironvariableerror!
\n");
exit
(1);
}
while((n=getline(fd,buf))!
=0){
getenviron(n,buf);
}
envhis.start=0;
envhis.end=0;
head=end=NULL;
}
intpipel(char*input,intlen)
{char*argv[10][30];
char*filename[0];
inti,j,k,is_bg=0;
intli_cmd=0;
intfd[10][1],pipe_in=-1;
intpipe_out=-1,flag=0;
pid_tpid;
for(i=0,j=0,k=0;i<=len;i++){
if((input[i]=='')||(input[i]=='\t')||(input[i]=='\0')||
(input[i]=='|')||(input[i]=='>')||(input[i]=='\n')){
if((input[i]=='|')||(input[i]=='>')){
if(input[i]=='>'){
flag=1;
}
if(j>0){
buf[j++]='\0';
argv[li_cmd][k]=(char*)malloc(sizeof(char)*j);
strcpy(argv[li_cmd][k],buf);
k++;
}
argv[li_cmd][k]=(char*)0;
li_cmd++;
k=0;
j=0;
}
if(j==0){
continue;
}else{
buf[j++]='\0';
if(flag==0){
argv[li_cmd][k]=(char*)malloc(sizeof(char)*j);
strcpy(argv[li_cmd][k],buf);
k++;
}else{
filename[0]=(char*)malloc(sizeof(char)*j);
strcpy(filename[0],buf);
}
}
j=0;
}else{
if((input[i]=='&')&&(input[i]=='\0')){
is_bg=1;
continue;
}
buf[j++]=input[i];
}
}
argv[li_cmd][k++]=NULL;
for(i=0;i<=10;i++){
fd[i][FD_READ]=NO_PIPE;
fd[i][FD_WRITE]=NO_PIPE;
}
for(i=0;i if(pipe(fd[i])==-1){ printf("Cannotopenpipe! \n"); return0; } } for(i=0;i if(is_founded(argv[i][0])==0){ printf("Cannotfoundcommand! \n"); break; } } if(i! =0){ pipe_in=fd[i-1][FD_READ]; }else{ pipe_in=NO_PIPE; } if(i! =li_cmd){ pipe_out=fd[i][FD_WRITE]; }else {if(flag==1){ if((pipe_out=open(filename[0],O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR))==-1){ printf("Cannotopen%s\n",filename[0]); return0; } }else{ pipe_out=NO_PIPE; } } if((pid=fork())<0){ printf("Forkfailed! \n"); return0; } if(pid==0){ if(pipe_in==NO_PIPE){ close(pipe_in); } if(pipe_out==NO_PIPE){ close(pipe_out); } if(pipe_out! =NO_PIPE){ dup2(pipe_out,1); close(pipe_out); } if(pipe_in! =NO_PIPE){ dup2(pipe_in,0); close(pipe_in); } execv(buf,argv[i]); }else{ if(is_bg==0){ waitpid(pid,NULL,0); } close(pipe_in); close(pipe_out); } return0; } voidadd_history(char*inputcmd) { envhis.end=(envhis.end+1)%HISNUM; if(envhis.end==envhis.start){ envhis.start=(envhis.start+1)%HISNUM; } strcpy(envhis.his_cmd[envhis.end],inputcmd); } voidhistory_cmd() { inti,j=0; if(envhis.start==envhis.end){ return; } elseif(envhis.start for(i=envhis.start+1;i<=envhis.end;i++){ printf("%d\t%s\n",j,envhis.his_cmd[i]); j++; } }else{ for(i=envhis.start+1;i printf("%d\t%s\n",j,envhis.his_cmd[i]); j++; } for(i=0;i<=envhis.end;i++){ printf("%d\t%s\n",j,envhis.his_cmd[i]); j++; } } } voidcd_cmd(char*route) { if(route! =NULL){ if(chdir(route)<0) printf("cd;%sErrorfileordirectory! \n",route); } } voidjobs_cmd() { structNODE*p; inti=1; p=head; if(head! =NULL){ do { printf("%d%d%s\t%s\n",i,p->pid,p->state,p->cmd); i++; p=p->link; }while(p! =NULL); } else printf("Nojobs! \n"); } voidadd_node(char*input_cmd,intnode_pid) { structNODE*p; p=(structNODE*)malloc(sizeof(structNODE)); p->pid=node_pid; strcpy(p->state,input_cmd); strcpy(p->state,"running"); p->link=NULL; if(head==NULL){ head=p; end=p; }else{ end->link=p; end=p; } } voiddel_node(intsig,siginfo_t*sip) { structNODE*q; structNODE*p; intid; if(sig_z==1){ sig_z=0; gotoout; } id=sip->si_pid; p=q=head; if(head==NULL) gotoout; while(p->pid! =id&&p->link! =NULL){ p=p->link; } if(p->pid! =id) gotoout; if(p==head) head=head->link; else{ while(q->link! =p){ q=q->link; } if(p==end){ end=q; q->link=NULL; }else{ q->link=p->link; } } free(p); out: return; } voidsetflag(){ sig_flag=1; } voidctrl_z() { structNODE*p; inti=1; if(pid1==0){ gotoout; } if(head! =NULL){ p=head; while((p->pid! =pid1)&&(p->link! =NULL)){ p=p->link; } if(p->pid==pid1){ strcpy(p->state,"stopped"); }else { add_node(input,pid1); strcpy(end->state,"stopped"); } } else { add_node(input,pid1); strcpy(end->state,"stopped"); } sig_z=1; kill(pid1,SIGSTOP); for(p=head;p->pid! =pid1;p=p->link) { i++; } printf("[%d]\t%s\t%s\n",i,end->state,end->cmd); pid1=0; out: return; } voidbg_cmd(intjob_num) { structNODE*p; inti=0; p=head; for(i=1;i { p=p->link; } kill(p->pid,SIGCONT); strcpy(p->state,"running"); } voidfg_cmd(intjob_num) { structNODE*p; inti=0; p=head; for(i=1;i { p=p->link; } strcpy(p->state,"running"); strcpy(input,p->cmd); pid1=p->pid; signal(SIGTSTP,ctrl_z); kill(p->pid,SIGCONT); waitpid(p->pid,NULL,0); } intmain() { init_environ(); while (1) { charc; char*arg[20]; inti=0,j=0,k=0; intis_pr=0,is_bg=0; intinput_len=0,path; intpid=0,status=0; structsigactionaction; action.sa_sigaction=del_node; sigfillset(&action.sa_mask); action.sa_flags=SA_SIGINFO; sigaction(SIGCHLD,&action,NULL); signal(SIGTSTP,ctrl_z); path=get_current_dir_name(); printf("ysh@%s",path); while(((c=getchar())=='')||(c=='\t')||(c==EOF)) { ; } if(c=='\n') { continue; } while(c! ='\n') { buf[input_len++]=c; c=getchar(); } buf[input_len]='\0'; input=(char*)malloc(sizeof(char)*(input_len+1)); strcpy(input,buf); for(i=0,j=0,k=0;i<=input_len;i++) { if((input[i]=='<')||(input[i]=='>')||(input[i]=='|')) { if(input[i]=='|') { pipel(input,input_len); add_history(input); free(input); } else { redirect(input,input_len); add_history(input); free(input); } is_pr=1; break; } } if(is_pr==1) { continue; } for(i=0,j=0,k=0;i<=input_len;i++) { if((input[i]=='')||(input[i]=='\0')) { if(j==0) { continue; } else { buf[j++]='\0'; arg[k]=(char*)malloc(sizeof(char)*j); strcpy(arg[k++],buf); j=0; } } else { if((input[i]=='&')&&(input[i+1]=='\0')) { is_bg=1; continue; } buf[j++]=input[i]; } } if(strcmp(arg[0],"exit")==0) { add_history(input); printf("Byebye! \n"); free(input); break; } if(strcmp(arg[0],"history")==0) { add_history(input); history_cmd(); free(input); continue; } if(strcmp(arg[0],"cd")==0) { add_history(input); for(i=3,j=0;i<=input_len;i++) { buf[j++]=input[i]; } buf[j]='\0'; arg[1]=(char*)malloc(sizeof(char)*j); strcpy(arg[1],buf); cd_cmd(arg[1]); free(input); continue; } if(strcmp(arg[0],"jobs")==0) { add_history(input); jobs_cmd(); free(input); continue; } if(strcmp(arg[0],"bg")==0) { add_history(input); for(i=0;i<=input_len;i++) { if(input[i]=='%') { break; } } i++; for(;i<=input_len;i++) { buf[j++]=input[i]; } buf[j]='\0'; arg[1]=(char*)malloc(sizeof(char)*j); strcpy(arg[1],buf); bg_cmd(atoi(arg[1])); free(input); continue; } if(strcmp(arg[0],"fg")==0) { add_history(input); for(i=0;i<=input_len;i++){ if(input[i]=='%'){ break; } } i++; for(;i<=input_len;i++) { buf[j++]=input[i]; } buf[j]='\0'; arg[1]=(char*)malloc(sizeof(char)*j); strcpy(arg[1],buf); fg_cmd(atoi(arg[1])); free(input); continue; } if(is_pr==0) { arg[k]=(char*)malloc(sizeof(char)); arg[k]=NULL; if(is_founded(arg[0])==0) { printf("Thiscommandisnotfouned! \n"); for(i=0;i<=k;i++) { free(arg[i]);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告 shell 程序