Linux系统编程--实现简单shell

上个博客我们讲了进程如何替换,以及exec函数族是,接下来我们来应用这些函数以及之前学的知识来实现一个简单shell。
如果不太清楚,请先看看之前的内容;
1.进程创建
2.进程等待
3.进程替换
我们先看系统的shell是如何实现?
在这里插入图片描述

我们敲一行命令,然后按回车,这个命令就被执行,玩了之后他他又返回到原来的状态,这个命令还可以加上选项,例这些选项之间用空格间隔开。并且空格可以是多个。如下图,
从左到右表示时事件发生的次序,shell从用户读入字符串“ls",然后建立一个心得进程,接着在这个心得进程里面运行新的程序,并等待新的进程运行结束。接着shell读取新的一行命令,建立一个新的进程,生在这个进程中运行程序,并等待这个进程结束。
在这里插入图片描述

所以我们要实现一个shell,就需要循环下面几步:

1. 获取命令行
2. 解析命令行
3. 建立一个子进程(fork)
4. 替换子进程(exec)
5. 父进程等待子进程退出(wait)

代码如下:

/*模拟实现简易shell
 * 功能:myshell> ls
 *      能够执行各种命令
*/
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<string.h>


char *argv[32];
int argc = 0;
int param_parse(char *buff)     //解析字符串的函数
{
    //ls -l -a
    if(buff==NULL)  //字符串为空,跳出
        return -1;
    char *ptr = buff;//ptr用来存放当前字符串
    char *tmp = ptr;
    argc = 0;
    while((*ptr)!='\0')
    {
        //当遇到空格,并且下个字符不是空格
        //将空格空格位置置'\0',此时就相当于截断了一个字符串,然后将这个字符串保存再字符指针数组里面
        //然后将使用argv[argc]来保存字符串的位置
        if(*ptr == ' '&&*(ptr+1)!=' ')
        {
            *ptr='\0';
            argv[argc]=tmp;//保存空格之前的字符串
            
            tmp=ptr+1;//将指针指向空格的下个字符
            argc++;//数组下标+1
        }
        ptr++;//ptr往后遍历
    }
    argv[argc++] = tmp;//循环跳出,说明已经是最后一个字符串,保存后再将下个指针置NULL
    argv[argc] = NULL;
    return 0;
}

int exec_cmd()  //创建子进程,并且替换
{
    int pid = 0;
    pid = fork();//创建子进程
    if(pid < 0)
    {
        return -1;
    }
    else if(pid == 0)//如果是子进程,则替换程序
    {
        execvp(argv[0],argv);//进行替换
        exit(0);//执行完要退出进程,不能return 
    }
    //到这里就说明是父进程
    int statu;//用来保存进程推出的信息
    wait(&statu);//获取信退出信息
    if(WIFEXITED(statu))//判断子进程是否正常退出,非0则表示正常退出
    {
        printf("%s\n",strerror(WEXITSTATUS(statu)));//获取后取其里面的退出码,再用strerroe打印出退出信息
    }
    return 0;
}

int main()
{
    char buff[1024] = {0};
    while(1)
    {    
        printf("myshell> ");
        scanf("%[^\n]%*c",buff);
        //%[^\n]获取数据直到遇到\n为止
        //%*c  清空缓冲区,数据都不要了,这样做是为了不对下次的缓冲区中输入的指令造成影响
        printf("%s\n",buff);
        param_parse(buff);
        exec_cmd();
    }
    return 0;
}

效果如下:

在这里插入图片描述

是不是还挺炫酷的捏!?

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值