头文件及全局变量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#define NUM 1024
#define SIZE 32
#define SEP " "
char cmd_line[NUM];//保存完整命令行
char *g_cmd[SIZE];//保存打散之后的命令行
模拟实现
int main()
{
while(1)//命令行解释器 不退出程序不退出
{
//1.打印提示信息
printf("[root@localhost myshell]# ");//加\n就会再令一行输出 不符预期
//不加又会存在于缓冲区 所以需要刷新缓冲区
fflush(stdout);
//void *memset(void *s, int c, size_t n);将某一块内存中的全部设置为指定的值。
memset(cmd_line,'\0',sizeof cmd_line);//sizeof 不加括号也可以计算大小
//2.读取用户的命令
//fgets <stdio.h> 从stream流里读取size个字节的数据放到s里面
//char *fgets(char *s, int size, FILE *stream);
if(fgets(cmd_line,sizeof cmd_line, stdin)==NULL)//没输入
{
continue;
}
//输入的时候会以换行结束 而换行也被读取 所以需要改掉
cmd_line[strlen[cmd_line]-1]='\0';
//3.命令行字符串解析
//cmd_line 是一整个字符串 对应功能要分开读取 所以需要拆分字符串
//strtok 从s开始找空格 找到了就用delim 将字符串分开
//char *strtok(char *s, char *delim)
g_cmd[0]=strtok(cmd_line,SEP);//SEP被宏定义为空格" " 需要是字符串形式
int index=1;//index可以理解为字符串的个数
//需要在源字符串继续拆分 参数需要传入NULL
while(g_cmd[index++]=strtok(NULL,SEP));// 先拆再判断while 全部拆完
//4.TODO
//linux有指令不需要父进程去做 比如cd ..
if(strcmp(g_cmd[0],"cd")==0)//strcmp返回 >0 =0 <0 对应字符串大于 等于 小于
{
//改变当前地址不需要子进程进程 子进程改变 父进程也不变
//chdir 改变当前路径到传入的路径
if(g_cmd[1]!=NULL)//cd命令有具体位置
{
chdir(g_cmd[1]);
continue;
}
}
//5.fork()
pid_t id=fork();
if(pid==0)
{
//子进程
printf("下面由子进程运行\n");
execvp(g_cmd[0],g_argv);// 输入 ls -a -l 刚好符合调用要求
exit(1);//进程未替换就退出
}
//父进程
int status=0;
pid_t ret=waitpid(id,&status,0);//阻塞等待
}
}