-
捕捉用户键盘输入 [ls -a -l]—char* gets(char* s)
-
解析输入信息,得到命令名称,运行参数 [ls] [-a] [-l]
-
创建子进程,给子进程通过命令名称进行程序替换(让子进程运行命令)
-
进程等待,等待子进程退出,防止出现僵尸进程
循环以上进程什么是内建命令?
在shell内部本身实现的功能,并非外部程序。并且内建功能,不需要创建子进程替换。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<unistd.h>
#include<sys/wait.h>
int main()
{
while(1)
{
//捕捉用户键盘输入
printf("[user@host path]$ "); //打印 "[当前用户@主机名 当前所在路径]$"
fflush(stdout); //刷新缓冲区
char cmd[1024] = {0}; //创建字符数组用来保存输入命令
fgets(cmd, 1023, stdin); //从标准输入读取1023个字符放入cmd数组当中
cmd[strlen(cmd) - 1] = '\0'; //将输入命令时敲的最后一个换行符替换'\0'
//字符串的解析
char* ptr = cmd; //获取到字符串的起始位置
int argc = 0; //参数个数
char* argv[32] = {NULL}; //创建字符指针数组保存参数内容
while(*ptr != '\0' ) //若不为当前字符串的末尾
{
if(!isspace(*ptr)) //若当前字符不为空白符
{
argv[argc++] = ptr; //保存字符串起始地址,增加参数个数
while(*ptr != '\0' && !isspace(*ptr)) //找到下一个空白符的位置
ptr++;
*ptr = '\0'; //将获取的当前单个字符串参数的结束位置置为'\0',从而完成对当前字符串参数的获取
}
ptr++; //若当前字符为空白符则指针继续向后走
}
argv[argc] = NULL; //将保存参数命令数组的最后一个参数置为NULL
//cd命令是shell的内建命令,即在shell内部实现的功能,并非外部程序
if(strcmp(argv[0], "cd") == 0) //若当前命令为cd命令
{
chdir(argv[1]); //改变当前工作路径
continue; //因为是内建功能,不需要创建子进程替换
}
pid_t pid = fork(); //创建子进程
if(pid < 0)
{
continue; //创建子进程失败,但是shell并不会退出,continue继续获取下一个命令
}
else if(pid == 0)
{
execvp(argv[0], argv); //通过子进程运行命令,完成程序替换,argv[0]为程序自身,argv为运行参数
exit(-1); //若进程替换失败则退出子进程
}
wait(NULL); //进程等待,等待子进程退出,防止出现僵尸进程
}
return 0;
}