操作系统第三次实验作业 linux中myecho.c mycat2.c sh2.c实现

一、作业 myecho.c

  实现系统程序 echo 相同的功能

  能通过如下测试

$ ./myecho abc
abc
$ ./myecho abc xyz
abc xyz
$ ./myecho abc >log.txt
$ cat log.txt
abc

代码如下: 

#include <stdlib.h>
#include <stdio.h>

int main(int agrc,char *agrv[]){
	int i;
	for(i=1;i<agrc;i++){
		printf("%s",agrv[i]);
	}
	printf("\n");
	return 0;
}	

二、作业 mycat2.c

  实现系统程序 cat 相同的功能

  能通过如下测试

# 创建一个测试文件 log.txt,内容为 hello
$ echo hello >log.txt

# 显示 log.txt 的内容 
$ ./mycat log.txt 
hello

# 将 mycat 的标准输入定向到文件 log.txt
$ ./mycat <log.txt
hello

# 将 mycat 的标准输出定向到文件 out.txt
$ ./mycat >log.txt
world
ctrl-D 结束输入

老师ppt上的代码,直接照着敲就行:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include<sys/stat.h>

void copy(int src_fd,int dst_fd)
{
	char buf[512];
	int count;
	while(count = read(src_fd,buf,512))
		write(dst_fd, buf, count);
}
int main(int argc,char *argv[])
{
	int fd;
	if(argc==1)
		fd = 0;
	else{
		fd = open(argv[1],O_RDONLY);
	}	
	copy(fd,1);
}	

三、作业 sh2.c

  实现shell程序,要求在第1版的基础上,增加文件重定向功能

  重定向输入

  重定向输出

  重定向追加

思路:

        

  • 输入重定向:指的是重新指定设备来代替键盘作为新的输入设备;
  • 输出重定向:指的是重新指定设备来代替显示器作为新的输出设备

        <         输入

        >        覆盖输出

        >>      追加输出

         

 老师给的提示:

        while (1) {
        char *argv[];
        int argc;
        char *output;
        char *input;
        gets(line);
        parse line;        //分词实现

        // line = "echo abc >log.txt";
        // argv = {"echo", "abc", NULL};
        // argc = 2;
        // output = "log.txt"
        pid = fork();
        if (pid == 0) {
            redirect stdout to log.txt;        //重定向实现
            execvp(argv[0], argv);
        }
        wait();
}

        个人觉得难度在于分词和检验'<','>','>>'的操作,c基础不好的很容易出现各种各样的问题。分词处理好后,就是把之前写的mysys函数直接套用加上改一下输入输出重定向就行了。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

//定义全局变量,建议还是用个结构体保存比较好
char *argv[20];    //命令或地址
int argc;           //命令或地址数
char *output;        //输出文件名
char *input;        //输入文件名
int append;         //追加模式,1:追加 0:覆盖
    
void parse(char *command)
{    //按空格“ ”进行分词 并将其保存在argv[]中
    //如“echo ab >log.txt" 分词后agrc=3,agrv[]={"echo","ab",">log.txt"}
	char *line=(char *)malloc(sizeof*(command));
	strcpy(line,command);

	char *word;
	word=strtok(line," ");
	while(word!=NULL)
	{
		argv[argc++]=word;
		word=strtok(NULL," ");
	}
}
void parse_test(char *s){    //将argv最后一个字串进行“<”,“>>”,“>”检验
   	//如agrc=3 agrv[]={"echo","ab",">log.txt"} output=NULL则s=">log.txt"
    //检验后 agrc=2 agrv[]={"echo","ab"} output="log.txt"
 
    if(s[0]=='<'){    //s代表argv最后一个字符">log.txt"
		input=&s[1];
		argc--;        //
		argv[argc]=NULL;
	}
	else if(s[0]=='>'&&s[1]=='>'){
		output=&s[2];
		append=1;
		argc--;
		argv[argc]=NULL;
	}
	else if(s[0]=='>'){
		output=&s[1];
		argc--;
		argv[argc]=NULL;
	}
}
void child(){    //子进程
	int fd;
	if(input!=NULL){
		fd=open(input,O_RDONLY,0666);    
		dup2(fd,0);            //重定向    0号描述符指向了fd描述符所指位置
		close(fd);    
	}
	if(output!=NULL&&append==0){
		fd=open(output,O_RDWR|O_CREAT,0666);
		dup2(fd,1);
		close(fd);
	}
	if(append!=0){
		fd=open(output,O_RDWR|O_APPEND|O_CREAT,0777);
		dup2(fd,1);
		close(fd);
	}
	execvp(argv[0],argv);
}
int main(){
	while(1){
		printf(">");

		char line[20];
		fgets(line,20,stdin);    //如之前所说,建议用fgets读
		line[strlen(line)-1]=0;    //把line最后的回车变成“/0”

//全局变量初始化
		argc=0;
		for(int i=0;i<20;i++)
			argv[i]=NULL;
		input=NULL;
		output=NULL;
		append=0;

		parse(line);
		
		parse_test(argv[argc-1]);
		
        //下面就相当之前写的mysys.c部分
		if(!strcmp(argv[0],"cd")){
			chdir(argv[1]);	
		}
		else if(!strcmp(argv[0],"exit")){
			exit(1);
		}
		else{
		int pid=fork();
		if(pid==0){
			child();
		}	
	}
	wait(NULL);
}
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值