Fork me on GitHub

模拟实现简单的shell

模拟实现一个简易的shell

shell读取一行输入,建立一个新的进程,在这个进程中运行程序,并等待这个进程结束

  • 过程分析
  1. 获取命令行
  2. 解析命令行
  3. 建立一个子进程(fork)
  4. 替换子进程(execvp)
  5. 父进程等待子进程退出(wait)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
* 1. 写一个shell入口提示要输入信息
* 2. scanf接收一个输入信息
* 3. 创建子进程
* 4. 程序替换
*/

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

int main()
{
while(1){
printf("minishell> ");
//清空标准输出流缓冲区
fflush(stdout);
char cmd[1024] = {0};
//^\n:scanf本身是遇到空格就要获取一次,这样的话就无法获取
// 到一个完整的命令,因此‘%[^\n]’表示的是获取数据直到
// 遇到\n为止
//%*c:将缓冲区中的字符都取出来,但是不要它,直接丢掉
// 目的是为了将最后的\n从缓冲区取出来,防止陷入死循环
//scanf的返回值是成功读入的项数
if(scanf("%[^\n]%*c",cmd) != 1){
getchar();
}

//解析获取到的命令
char *ptr = cmd;
char *argv[32] = {NULL};
int argc = 0;
argv[argc++] = ptr;
while(*ptr != '\0'){
//int isspace(int c)
//用于判断一个字符是否是:\t \n \r 空格
//解析一个字符串时候这里就是对空格的判断
if(isspace(*ptr)){
while(isspace(*ptr) && (*ptr != '\0')){
*ptr++ = '\0';
}
argv[argc++] = ptr;
}
ptr++;
}

if(fork() == 0){
execvp(argv[0],argv);
}
//需要等待的原因:
//1. 避免产生僵尸子进程
//2. 是为了等待子进程运行完毕,让程序逻辑更加完善
wait(NULL);
}
return 0;
}
  • 效果展示

avater

avater

-------------本文结束感谢您的阅读-------------

本文标题:模拟实现简单的shell

文章作者:李煜哲

发布时间:2018年12月13日 - 21:12

最后更新:2018年12月13日 - 21:12

原始链接:http://yoursite.com/2018/12/13/模拟实现简单的shell/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者

觉得好的话就打赏一下吧