1.基本思路
首先需要知道的是xshell是一个外壳程序,它运行起来直到用户退出才会停止,所以开始直接设置一个死循环。然后按照下面的步骤
- 打印出提示用户的信息
- 获取用户输入的指令,选项
- 将字符串命令分析为多个子串参数("ls -a -l" >> "ls" "-a" "-l")
- 创建子进程(fork函数),把分析好的参数交给子进程运行(execvp),这样即使运行失败,影响的也只是子进程,父进程依旧可以继续运行。
- 补充cd命令是内置命令,如果使用子进程运行cd命令,改变的只是子进程的目录,我们需要使用系统接口chdir函数来改变父进程当前的工作目录。
2.代码实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include <sys/wait.h>
#define num 1024
#define size 35
char cmdstr[num];
char* argv[size];
int main()
{
while(1)
{
//1.打印出提示信息[an@localhost myxshell]$,使用fflush函数(将缓冲区内的内容刷新出来)
因为使用\n刷新缓冲区的内容会出现换行.
printf("[an@localhost myxshell]$");
fflush(stdout);
//sleep(6);
//2.获取用户输入
memset(cmdstr, '\0', sizeof cmdstr);
if (fgets(cmdstr, sizeof cmdstr, stdin) == NULL)
{
continue;
}
//把\n置为\0
cmdstr[strlen(cmdstr) - 1] = '\0';
//3.解析命令"ls -a -l" > "ls" "-a" "-l"
int idex = 0;
argv[idex++] = strtok(cmdstr, " ");
//ls 命令展示增加颜色
if (strcmp(argv[0], "ls") == 0)
argv[idex++] = "--color=auto";
while (argv[idex++] = strtok(NULL, " "));
//内置命令cd,让父进程(shell)自己执行的命令
if (strcmp(argv[0],"cd") == 0)
{
if (argv[1])
chdir(argv[1]);
}
//测试代码
//idex = 0;
//for (; argv[idex]; idex++)
//{
//printf("agrv[%d]:%s\n", idex, argv[idex]);
//}
//frok创建子进程执行命令
pid_t pid = fork();
if (pid == 0)
{
//child
execvp(argv[0], argv);
exit(-1);
}
//father
int status;
int res = waitpid(-1, &status, 0);
if (res > 0)
{
// printf("wait success exitcode:%d\n", WEXITSTATUS(status));
}
}
return 0;
}