目录
从显示屏获取输入字符流
分割字符串 取出命令名称及选项
去除输入时多按的那个换行符
创建子进程,实现程序替换
如果替换失败,进程终止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 10char 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;
}
最后
加油