Linux下minishell项目的编写

项目目标

1.编写函数打印初始界面以及显示输入的命令(由于程序一直执行,需要在循环内执行)

2.编写接收用户输入的命令的函数

3.编写使命令与功能匹配的函数

4.将界面输入的字符串分割为命令以及传入函数的数据

5.完成minishell的基本功能函数:

        ls  :显示目录下文件(不包括隐藏文件) 

        ls -a :显示所有文件         

        touch   :创建一个文件
        rm:移除一个文件
        mkdir :创建一个目录
        rmdir:移除一个目录
        cd :切换目录
        cp:拷贝文件
        mv:移动文件内容
        pwd:显示当前目录
        cat:显示文件内容
        chmod  :改变文件权限
        ln:创造文件链接

2.5.(补充任务)将输入的命令写入时间日志

6.将不同文件下的函数建立关联

7.将函数进行封装

目标一的实现:

使用printf函数打印出基础界面,再用getcwd获得本地目录的值,由于值过于长,因此通过while以及if的判断,将打印出来的内容只显示最后一个子目录

其实现子函数如下:

int show(void)
{
	char tmp[1024]={0};
	char *ptm=NULL;
	getcwd(tmp,sizeof(tmp));
	ptm=tmp;
	while(*ptm !='\0')
	{
		ptm++;
	}
	while(*ptm !='/')
	{
		ptm--;
	}
	if(strcmp(tmp,"/")!=0)
	{
		ptm++;
	}
	printf("[linux@ubuntu:%s]",ptm);
}

目标二的实现:

在主函数中设置一个数组,将其传输到目标二的函数中,用fgets函数将界面上输入的值写入数组中(用stdin),并在数组的最后一项补充‘\0’-----作用为:在目标三中使匹配能够完成。

//主函数中定义数组pcmd(maxlen);
int getuse(char *pcmd,int maxlen)
{
	fgets(pcmd,maxlen,stdin);
	pcmd[strlen(pcmd)-1]='\0';
}

目标三与四的实现:

将目标二中的数组与预设的命令符号通过strncmp对比,若符合,通过strtok函数对数组中的字符串按空格进行切割,在分别用指针保存切割后的指令,一般第一个指令为命令,后面的指令为输入参数。

int str(char *cmd)
{
if(!strcmp(cmd,"exit"))
	{
		break;
	}
	if(!strncmp(cmd,"cd",2))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		cd(token);
	}
	if(!strncmp(cmd,"cp",2))
	{
		char *age=NULL;
		char *agv=NULL;
		char *token=strtok(cmd," ");
		age =strtok(NULL," ");
		agv =strtok(NULL," ");
		cp(age,agv);
	}
	if(!strncmp(cmd,"chmod",5))
	{
		char *age=NULL;
		char *agv=NULL;
		char *token=strtok(cmd," ");
		age =strtok(NULL," ");
		agv =strtok(NULL," ");
		mychmod(age,agv);
	}
	if(!strncmp(cmd,"ls-l",4))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		lsl(token);
	}
	if(!strcmp(cmd,"ls"))
	{
		ls();
	}
	if(!strncmp(cmd,"ls-a",4))
	{
		lsa();
	}
	if(!strncmp(cmd,"mkdir",5))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		mymkdir(token);
	}
	if(!strncmp(cmd,"rmdir",5))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		myrmdir(token);
	}
	if(!strncmp(cmd,"ln",2))
	{
		char *age=NULL;
		char *agv=NULL;
		char *token=strtok(cmd," ");
		age=strtok(NULL," ");
		agv=strtok(NULL," ");
		 ln(age,agv);
	}
	if(!strncmp(cmd,"mv",2))
	{
		char *age=NULL;
		char *agv=NULL;
		char *token=strtok(cmd," ");
		age =strtok(NULL," ");
		agv =strtok(NULL," ");
		mv(age,agv);
	}
	if(!strncmp(cmd,"touch",5))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		touch(token);
	}
	if(!strncmp(cmd,"cat",3))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		cat(token);
	}
	if(!strncmp(cmd,"rm",2))
	{
		char *token=strtok(cmd," ");
		token =strtok(NULL," ");
		rm(token);
	}
	if(!strcmp(cmd,"pwd"))
	{
		pwd();
	}
}

目标五的实现

按照ubantu的shell中的基本功能函数编写函数:

ls功能:先使用getcwd函数获得目录地址,用opendir打开目录,并通过readdir读取目录,当读取到空时停止读取,读取到隐藏目录时,跳过,并将读取到的目录打印出来

#include"head.h"
int ls(void)
{
	char *a=NULL;
	DIR *b=NULL;
	struct dirent *c=NULL;
	char *ml=NULL;
	a=getcwd(ml,256);
	b=opendir(a);
	while(1)
	{
		c=readdir(b);
		if(NULL==c)
		{
			break;
		}
		if('.'==c->d_name[0])
		{
			continue;
		}
		printf(" %s ",c->d_name);
	}
	printf("\n");
	return 0;
}

ls -a功能:将ls的功能删减跳过隐藏文件即可

touch功能:使用fopen函数,打开方式为w即可

#include"head.h"
int touch(char *agv)
{
	FILE *a=NULL;
	char *p=NULL;
	p=agv;
	a=fopen(p,"w");
	fclose(a);
}

rm功能:使用remove函数

mkdir功能 :使用mkdir函数

rmdir:使用rmdir函数

cd :使用chdir函数

mv:使用rename函数

pwd:使用getcwd函数获得目录并打印       

ln:使用link函数链接ab文件

 cat:使用r方式打开文件,并将内容存到数组中,使用fputc函数将数组内容打印到终端上

#include"head.h"
int cat(char *q)
{
	FILE *tmp=NULL;
	char d;
	tmp=fopen(q,"r");
	while(1)
	{
		d=fgetc(tmp);
		fputc(d,stdout);
		if(d==EOF)
		{
			break;
		}
	}
	printf("\n");
}

 chmod  :先将从终端输入的字符型数字改变为八进制数字(strtol函数),然后使用chmod函数

#include"head.h"
int mychmod(char *age,char *agv)
{
	mode_t mode =0;
	mode =strtol(agv,NULL,8);
	printf("%d",mode);
	chmod(age,mode);
}

 cp:将传入的文件用r打开并存到数组中,用w打开传入的目标文件,用fgetc得到数组中的内容,用fputc写入目标文件即可

#include"head.h"
int cp(char *age,char *agv)
{
	FILE *tmp=NULL;
	FILE *aim=NULL;
	char *a=NULL;
	char *b=NULL;
	a=age;
	b=agv;
	char c[4096]={0};
	char d;
	tmp=fopen(a,"r");
	aim=fopen(b,"w");
	while(1)
	{
		d=fgetc(tmp);
		fputc(d,aim);
		if(d==EOF)
		{
			break;
		}
	}
}

目标六的实现

1.创造一个包含目标5实现的函数的声明的头文件,并包括各个函数所需的头文件

#ifndef __HEAD_H__
#define __HEAD_H__
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<dirent.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
#include<stdlib.h>
#include<string.h>
extern int ls(void);
extern int lsa(void);
extern int lsl(const char *agv);
extern int touch(char *agv);
extern int rm(char *agv);
extern int mymkdir(char *agv);
extern int myrmdir(char *agv);
extern int cd(char *agv);
extern int cp(char *age,char *agv);
extern int mv(char *age,char *agv);
extern int pwd(void);
extern int mychmod(char *age,char *agv);
extern int cat(char *q);
extern int ln(char *age,char *agv);

#endif

2.使用Makefile将所有有关文件关联并用make一起编译

OBJ=a.out
OBJT=main.c touch.c cd.c ls-l.c ls.c ls-a.c mkdir.c rmdir.c cat.c rm.c pwd.c cp.c mv.c ln.c chmod.c 	

$(OBJ):$(OBJT)
	gcc $^ -o $@

目标七的实现

用tar -zxvf a.out tar.gz 将a.out压缩,a.out即为应用名,运行文件名可以在Makefile中更改,压缩包就是应用包。

附:目标2.5与主函数

目标2.5:在getuse中使用fopen用w打开一个文件,对文件写入存有输入命令的数组以及输入时间。

int getuse(char *pcmd,int maxlen)
{
	FILE *a=NULL;
	time_t c;
	struct tm *d=NULL;
	fgets(pcmd,maxlen,stdin);
	pcmd[strlen(pcmd)-1]='\0';
	time(&c);
	d =localtime(&c);
	a=fopen("day.txt","a+");
	fprintf(a,"[%04d-%02d-%02d %02d:%02d:%02d]\n",d->tm_year+1900,d->tm_mon+1,d->tm_mday,d->tm_hour,d->tm_min,d->tm_sec);
	fwrite(pcmd,25,1,a);
	fputc('\n',a);
	fclose(a);
}

主函数将getuse、show、str包含即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值