
图1:模拟shell的流程图
实现了cat、cp、ls、ls -l、pwd等命令的功能,通过宏定义以及switch语句实现了对外部命令文件的选择,主函数中while(1)实现模拟多次输入命令,使用opendir、readdir、closedir、数个储存了文件详细信息的结构体,如dirent、stat、tm、passwd、group完成ls和ls -l的功能。
Myshell.c
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<ctype.h>
#include<sys/wait.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#include<sys/stat.h>
#include<dirent.h>
#include<sys/types.h>
#define cal 1
#define cat 2
#define cp 3
void Myfork(int flag, char* const argv[], char* const envp[])
{
if(fork() == 0)
{
switch(flag)
{
case cal:
if(execve("cal", argv, envp) == -1)
printf("Exec Failed");
break;
case cat:
if(execve("cat", argv, envp) == -1)
printf("Exec Failed");
break;
case cp:
if(execve("cp", argv, envp) == -1)
printf("Exec Failed");
break;
default:
break;
}
}
wait(NULL);
}
void Myls(void)
{
DIR* dir = opendir(".");
struct dirent* info = NULL;
while((info = readdir(dir)) != NULL)
{
if(strcmp(info->d_name,".") == 0)
continue;
if(strcmp(info->d_name,"..") == 0)
continue;
printf("%s ",info->d_name);
}
closedir(dir);
printf("\n");
}
//DIR *opendir(const char name);
//struct dirent readdir(DIR dir);
//int closedir(DIR *dir);
void Myls_l(void)
{
DIR* dir = opendir(".");
struct dirent* info = NULL;
struct tm* time = NULL;
struct passwd* pw = NULL;
struct group* gp = NULL;
struct stat st;
while((info = readdir(dir)) != NULL)
{
if(strcmp(info->d_name,".") == 0)
continue;
if(strcmp(info->d_name,"..") == 0)
continue;
stat(info->d_name, &st);
pw = getpwuid(st.st_uid);
gp = getgrgid(st.st_gid);
time = localtime(&st.st_mtime);
switch (st.st_mode & S_IFMT) //判断文件类型
{
case S_IFBLK: printf("b"); break; //块设备类型
case S_IFCHR: printf("c"); break; //字符类型
case S_IFDIR: printf("d"); break; //目录类型
case S_IFIFO: printf("p"); break; //管道类型
case S_IFLNK: printf("l"); break; //链接类型
case S_IFREG: printf("-"); break; //文件类型
case S_IFSOCK: printf("s"); break; //套接字类型
default: printf("?"); break; //无法识别类型
}
for(int i=8; i>=0; i--)
{
if(st.st_mode & (1 << i))
{
switch(i % 3)
{
case 2: printf("r"); break;//文件该处具有读权限
case 1: printf("w"); break;//文件该处具有写权限
case 0: printf("x"); break;//文件该处具有执行权限
}
}
else
printf("-");
}
printf(" %d ", st.st_nlink);
printf("%s ", pw->pw_name);
printf("%s ", gp->gr_name);
printf("%6d ", st.st_size);
printf("%2d月 %2d日 %2d:%2d ", time->tm_mon + 1,
time->tm_mday, time->tm_hour, time->tm_min);
printf("%s\n",info->d_name);
}
closedir(dir);
}
void Mypwd(void)
{
char buffer[1024];
getcwd(buffer, 1024);
printf("%s\n", buffer);
}
int main(int argc, char* const argv[], char* const envp[])
{
char cmd[20] = {0};
while(1)
{
printf("[Myshell]# ");
scanf("%s",cmd);
if(strcmp(cmd,"exit") == 0)
exit(0);
else if(strcmp(cmd,"ls-l") == 0)
Myls_l();
else if(strcmp(cmd,"ls") == 0)
Myls();
else if(strcmp(cmd,"pwd") == 0)
Mypwd();
else if(strcmp(cmd,"cal") == 0)
Myfork(cal, argv, envp);
else if(strcmp(cmd,"cat") == 0)
Myfork(cat, argv, envp);
else if(strcmp(cmd,"cp") == 0)
Myfork(cp, argv, envp);
else
printf("invalid cmd");
}
return 0;
}
cal.c 其实就是一个简单的加减乘除的计算器
#include<stdio.h>
int main()
{
int flag = 1,sum,i;
char f;
scanf("%d",&sum);
while(1)
{
scanf("%c",&f);
if(f == '=') break;
scanf("%d",&i);
if(f == '+') sum += i;
else if(f == '-') sum -= i;
else if(f == '*') sum *= i;
else if(f == '/')
{
if(i == 0 ) flag = 0;
else sum /= i;
}
else flag = 0;
}
if(flag == 0) printf("ERROR");
else printf("%d",sum);
return 0;
}
cat.c 实现linux中查看文件内容的功能
#include<stdio.h>
#include<string.h>
int main()
{
FILE *fp;
char ch;
char filename[20] = {0};
scanf("%s",filename);
fp = fopen(filename, "r");
if(fp==NULL)
printf("can not open!\n");
else
{
fscanf(fp,"%c",&ch);
while(!feof(fp))
{
putchar(ch);
fscanf(fp,"%c",&ch);
}
fclose(fp);
}
printf("\n");
return 0;
}
cp.c 实现linux中复制文件的功能 可以是相对路径也可以是绝对路径
#include <stdio.h>
#include <stdlib.h>
long FileCopy(FILE* filesource, FILE* filetarget)
{
int BufferLen = 1024;
char* mbuffer = (char*)malloc(BufferLen);
long sumbytes=0;
while(fread(mbuffer, 1, 1, filesource) > 0)
{
sumbytes += 1;
fwrite(mbuffer,1,1,filetarget);
}
fflush(filetarget);
free(mbuffer);
return sumbytes;
}
int main()
{
char source[60];
char target[60];
long filesize = 0;
scanf("%s", source);
scanf("%s", target);
FILE* filesource = fopen(source,"r+");
FILE* filetarget = fopen(target,"w+");
filesize = FileCopy(filesource, filetarget);
if(filesize == 0)
printf("FileCopy Failed\n");
return 0;
}
本文介绍了作者编写的Myshell程序,它模拟了Linux shell的流程,包括cat、cp、ls、ls-l、pwd等命令,利用宏定义和switch语句选择外部命令,并通过opendir、readdir、closedir等API实现目录遍历和文件信息展示。同时,cal、ls-l和ls的具体实现也被详细阐述。

627

被折叠的 条评论
为什么被折叠?



