mini
今天我们接触了第一个工程文件,minishell工程文件
Minishell功能
- 项目背景
在linux操作系统中,用户对操作系统进行的一系列操作都不能直接操作内核,而是通过shell间接对内核进行操作。
Shell 是操作系统中的一种程序,它为用户提供了一种与操作系统内核和计算机硬件进行交互的界面。用户可以通过 Shell 输入命令来执行各种任务,如文件管理、程序执行和系统配置等。
我们此次目标是自己编写一个minishell软件,可以完成shell的的基础功能。
- 项目分析
该项目的实现主要分为三大步骤:
- 完成minishell界面设计
- 从终端接收用户输入的命令
- 调用函数实现用户命令
需要说明一点:我们在这里还添加了历史查看功能,输入history将会显示之前输入的命令记录。
- 流程图设计
分析
在实现chmod命令时,要注意将输入的字符串“0777”转换成八进制在进行判断!
1.界面显示
#include "terminal.h"
char path[1024] = {0};
char tempbuff[1024] = {0};
char history[1024] = {0};
/*********界面显示************/
void DisplayOrder(void)
{
char *p = NULL;
getcwd(path,sizeof(path));
p = path;
printf("linux@ubuntu:%s-",p);
fflush(stdout);
return;
}
2.接受命令并记录
int ReceiveOrder(void)
{
time_t t;
struct tm *t1;
FILE *fp = NULL;
fgets(tempbuff, sizeof(tempbuff), stdin);
tempbuff[strlen(tempbuff)-1] ='\0';
fp = fopen("/home/linux/Desktop/minishell/history.txt","a");
if(NULL == fp)
{
perror("open history.txt feiled!");
return -1;
}
time(&t);
t1 = localtime(&t);
fprintf(fp,"[%d-%d-%d %d:%d:%d] %s\n",(t1->tm_year)-1970,(t1->tm_mon)-1,t1->tm_mday,\
t1->tm_hour,t1->tm_min,t1->tm_sec,tempbuff);
fwrite(history,strlen(history),1,fp);
fclose(fp);
return 0;
}
3.执行命令
void DoOrder(void)
{
char *p = NULL;
p = strtok(tempbuff, " ");
if(!strcmp(p,"mkdir"))
{
p = strtok(NULL, "\0");
mymkdir(p);
}
else if(!strcmp(p,"rmdir"))
{
p = strtok(NULL, "\0");
myrmdir(p);
}
else if (!strcmp(p, "cd"))
{
p = strtok(NULL, "\0");
mycd(p);
}
else if (!strcmp(p, "rm"))
{
p = strtok(NULL, "\0");
myrm(p);
}
else if (!strcmp(p, "touch"))
{
p = strtok(NULL, "\0");
mytouch(p);
}
else if (!strcmp(p, "mv"))
{
p = strtok(NULL, "\0");
mymv(p);
}
else if (!strcmp(p, "cp"))
{
p = strtok(NULL, "\0");
mycp(p);
}
else if (!strcmp(p, "cat"))
{
p = strtok(NULL, "\0");
mycat(p);
}
else if (!strcmp(p, "chmod"))
{
p = strtok(NULL, "\0");
mychmod(p);
}
else if (!strcmp(p, "ls"))
{
if (NULL != (p = strtok(NULL, " ")) && !strcmp(p, "-l"))
{
mylsl();
}
else if (NULL != p && !strcmp(p, "-a"))
{
mylsa();
}
else
{
myls();
}
}
else if (!strcmp(p, "history"))
{
myhistory();
}
else if (!strcmp(p, "exit"))
{
exit(0);
}
return;
}
4.各部分功能的实现
#include "command.h"
/*************myhistory********************/
int myhistory(void)
{
FILE *fp = NULL;
char *fd = NULL;
char temp[1024] = {0};
fp = fopen("/home/linux/Desktop/minishell/history.txt","r");
if(NULL == fp)
{
perror("open history.txt feiled!\n");
return -1;
}
while(1)
{
fd = fgets(temp,sizeof(temp),fp);
if(NULL == fd)
{
break;
}
printf("%s",temp);
}
fclose(fp);
return 0;
}
/*************mymkdir**************/
int mymkdir(char *p)
{
int ret = 0;
ret = mkdir(p,0777);
if(0 == ret)
{
printf("创建文件夹成功!\n");
}
else
{
printf("创建文件夹失败!\n");
return -1;
}
return 0;
}
/**************myrmdir*************/
int myrmdir(char *p)
{
int ret = 0;
ret = rmdir(p);
if(0 == ret)
{
printf("删除文件夹成功! \n");
}
else
{
perror("删除文件夹失败!\n");
return -1;
}
return 0;
}
/**************mycd****************/
int mycd(char *p)
{
char *pp = NULL;
char *temppath = NULL;
char temp[1024] = {0};
int i = 0;
getcwd(temp,sizeof(temp));
temppath = temp + strlen(temp);
pp = strtok(p,"/");
if(!strcmp(pp,".."))
{
while(*temppath != '/')
{
temppath--;
}
*temppath = '\0';
chdir(temp);
pp = strtok(NULL,"\0");
if(pp != NULL)
{
chdir(pp);
}
}
else
{
chdir(p);
}
return 0;
}
/**************myrm****************/
int myrm(char *p)
{
if(!unlink(p))
{
printf("删除文件成功!\n");
}
else
{
perror("删除文件失败!\n");
return -1;
}
return 0;
}
/*****************mytouch**************/
int mytouch(char *p)
{
FILE *fp = NULL;
fp = fopen(p,"w");
if(NULL == fp)
{
perror("open feiled!");
return -1;
}
printf("创建普通文件成功!\n");
fclose(fp);
return 0;
}
/*****************mymv******************/
int mymv(char *p)
{
char *old = NULL;
char *new = NULL;
DIR *A = NULL;
old = strtok(p," ");
new = strtok(NULL, "\0");
A = opendir(new);
link(old,new);
unlink(old);
closedir(A);
return 0;
}
/***************mycp*******************/
int mycp(char *p)
{
char *str = NULL;
char *dst = NULL;
char *pp = NULL;
FILE *fp = NULL;
FILE *fp1 = NULL;
char *fd = NULL;
char cp[1024] = {0};
char temp[128] = {0};
str = strtok(p," ");
dst = strtok(NULL,"\0");
chdir(dst);
fp = fopen(str,"w");
if(NULL == fp)
{
perror;
return -1;
}
chdir(str);
getcwd(temp,sizeof(temp));
pp = temp+strlen(temp);
while(*pp != '/')
{
pp--;
}
pp++;
chdir(pp);
fp1 = fopen(str,"r");
if(NULL == fp1)
{
perror;
fclose(fp);
return -1;
}
while(1)
{
fd = fgets(cp,sizeof(cp),fp1);
if(NULL == fd)
{
break;
}
fputs(cp,fp);
}
fclose(fp);
fclose(fp1);
return 0;
}
/****************myls******************/
int myls(void)
{
char temp[1024] = {0};
DIR *open = NULL;
struct dirent *read;
getcwd(temp,sizeof(temp));
open = opendir(temp);
if(NULL == open)
{
return -1;
}
while(1)
{
read = readdir(open);
if(NULL == read)
{
break;
}
if('.' == *read->d_name)
{
continue;
}
printf("%s\n",read->d_name);
}
closedir(open);
return 0;
}
/***************mylsa******************/
int mylsa(void)
{
char temp[1024] = {0};
DIR *open = NULL;
struct dirent *read;
getcwd(temp,sizeof(temp));
open = opendir(temp);
if(NULL == open)
{
return -1;
}
while(1)
{
read = readdir(open);
if(NULL == read)
{
break;
}
printf("%s ",read->d_name);
}
printf("\n");
closedir(open);
return 0;
}
/***************mylsl******************/
int mylsl(void)
{
struct stat buf;
int ret = 0;
struct tm *ptm = NULL;
char temp[1024] = {0};
DIR *open = NULL;
struct dirent *read;
struct passwd *pwd = NULL;
struct group *grp = NULL;
char *pmon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
getcwd(temp,sizeof(temp));
open = opendir(temp);
if(NULL == open)
{
perror("已经是最后一个!\n");
return -1;
}
while(1)
{
read = readdir(open);
if(NULL == read)
{
break;
}
if('.' == *read->d_name)
{
continue;
}
ret = lstat(read->d_name, &buf);
if (-1 == ret)
{
return -1;
}
if (S_ISREG(buf.st_mode))
{
printf("-");
}
else if (S_ISDIR(buf.st_mode))
{
printf("d");
}
else if (S_ISCHR(buf.st_mode))
{
printf("c");
}
else if (S_ISBLK(buf.st_mode))
{
printf("b");
}
else if (S_ISFIFO(buf.st_mode))
{
printf("p");
}
else if (S_ISSOCK(buf.st_mode))
{
printf("s");
}
else if (S_ISLNK(buf.st_mode))
{
printf("l");
}
buf.st_mode & S_IRUSR ? putchar('r') : putchar('-');
buf.st_mode & S_IWUSR ? putchar('w') : putchar('-');
buf.st_mode & S_IXUSR ? putchar('x') : putchar('-');
buf.st_mode & S_IRGRP ? putchar('r') : putchar('-');
buf.st_mode & S_IWGRP ? putchar('w') : putchar('-');
buf.st_mode & S_IXGRP ? putchar('x') : putchar('-');
buf.st_mode & S_IROTH ? putchar('r') : putchar('-');
buf.st_mode & S_IWOTH ? putchar('w') : putchar('-');
buf.st_mode & S_IXOTH ? putchar('x') : putchar('-');
printf(" %ld", buf.st_nlink);
pwd = getpwuid(buf.st_uid);
printf(" %s", pwd->pw_name);
grp = getgrgid(buf.st_gid);
printf(" %s", grp->gr_name);
printf(" %ld", buf.st_size);
ptm = localtime(&buf.st_mtime);
printf(" %s %d %02d:%02d", pmon[ptm->tm_mon], ptm->tm_mday, ptm->tm_hour, ptm->tm_min);
printf(" %s\n", read->d_name);
}
closedir(open);
return 0;
}
/************mycat***************/
int mycat(char *p)
{
FILE *fp = NULL;
char temp[1024] = {0};
size_t fd = 0;
fp = fopen(p,"r");
if(NULL == fp)
{
perror("open feiled!");
return -1;
}
fd = fread(temp,sizeof(temp),1,fp);
if(0 == fread)
{
perror("读取错误!");
}
printf("%s\n",temp);
return 0;
}
/**************mychmod**************/
int mychmod(char *p)
{
char num[4] = {0};
unsigned char *pnum = NULL;
char *pname = NULL;
mode_t pp;
int A = 0;
pnum = num;
pnum = strtok(p," ");
pname = strtok(NULL,"\0");
pp = pnum[3]-'0' + (pnum[2]-'0')*8 + (pnum[1]-'0')*64;
A = chmod(pname,pp);
if(-1 == A)
{
perror("修改权限失败!\n");
}
else
{
printf("修改成功!\n");
}
return 0;
}
4.头文件及声明
#ifndef ___COMMAND_H__
#define ___COMMAND_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "terminal.h"
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
extern int mymkdir(char *p);
extern int myrmdir(char *p);
extern int mycd(char *p);
extern int myrm(char *p);
extern int mycp(char *p);
extern int mytouch(char *p);
extern int mymv(char *p);
extern int myls(void);
extern int mylsl(void);
extern int mylsa(void);
extern int mycat(char *p);
extern int mychmod(char *p);
extern int myhistory(void);
#endif
今天就到这里啦!谢谢大家!