目录
从显示屏获取输入字符流
分割字符串 取出命令名称及选项
去除输入时多按的那个换行符
创建子进程,实现程序替换
如果替换失败,进程终止exit
查看子进程情况
实现echo $?功能
实现cd
最终代码
基本思路 让父进程创建一个子进程,由这个子进程进行程序替换。父进程要对这个进程进行追踪、回收。具体实现模块如下:
从显示屏获取输入字符流
char* s=fgets(buffer,sizeof (buffer)-1,stdin);
assert(s!=NULL);
buffer[strlen (buffer)-1]=0;
(void*)s;
分割字符串 取出命令名称及选项
//切割字符串
myargv[0]=strtok(buffer," ");
int i=0;
if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)
{
myargv[++i] = (char*)"--color=auto";
}
while(myargv[i]!=NULL)
{
myargv[++i]=strtok(NULL," ");
}
创建子进程,实现程序替换
pid_t id =fork();
if(id==0)
{
//子进程
//程序替换
execvp(myargv[0],myargv);
//如果走到这里表示替换失败
exit(1);
}
查看子进程情况
//父进程
int status=0;
pid_t ret= waitpid(id,&status,0);
assert(ret > 0);
(void)ret;
quitcode=(status>>8)&0XFF;
quitsignal= (status & 0x7F);
实现echo $?功能
//实现echo $?功能
if(myargv[0]!=NULL&&myargv[1]!=NULL&&strcmp(myargv[0],"echo")==0)
{
if(strcmp(myargv[1],"$?")==0)
{
//输出上一个进程的退出码
printf("退出码为:%d\n",quitcode);
}
else
{
printf("%s\n",myargv[1]);
}
continue;
}
实现cd
//实现cd功能
if(myargv[0] != NULL &&strcmp(myargv[0],"cd")==0)
{
if(myargv[1]!=NULL)
{
chdir(myargv[1]);
}
continue;
}
最终代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#define B_NUM 1024
#define ARGV_NUM 10
char buffer[B_NUM];
char* myargv[ARGV_NUM];
int quitcode;
int quitsignal;
int main()
{
while(1)
{
printf("【用户名@服务器 当前目录】$");
fflush(stdout);
char* s=fgets(buffer,sizeof (buffer)-1,stdin);
assert(s!=NULL);
buffer[strlen (buffer)-1]=0;
(void*)s;
//切割字符串
myargv[0]=strtok(buffer," ");
int i=0;
if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)
{
myargv[++i] = (char*)"--color=auto";
}
while(myargv[i]!=NULL)
{
myargv[++i]=strtok(NULL," ");
}
//实现cd功能
if(myargv[0] != NULL &&strcmp(myargv[0],"cd")==0)
{
if(myargv[1]!=NULL)
{
chdir(myargv[1]);
}
continue;
}
//实现echo $?功能
if(myargv[0]!=NULL&&myargv[1]!=NULL&&strcmp(myargv[0],"echo")==0)
{
if(strcmp(myargv[1],"$?")==0)
{
//输出上一个进程的退出码
printf("退出码为:%d\n",quitcode);
}
else
{
printf("%s\n",myargv[1]);
}
continue;
}
pid_t id =fork();
if(id==0)
{
//子进程
//程序替换
execvp(myargv[0],myargv);
//如果走到这里表示替换失败
exit(1);
}
//父进程
int status=0;
pid_t ret= waitpid(id,&status,0);
assert(ret > 0);
(void)ret;
quitcode=(status>>8)&0XFF;
quitsignal= (status & 0x7F);
}
return 0;
}
最后
加油