linux下制作一个简易shell

做一个简单的shell

   1.首先输入一个命令,并且用一个字符数组来保存这个命令

   2.按照空格解析这个字符串(如果是用空格分割开的命令的话(ls  -l),将空格前后字符串分开保存在字符串数组中)

   3.创建一个子进程(fork()),然后替换子进程(execvp),让父进程等待子进程的退出然后释放掉子进程的资源(wait)。

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

int argc = 0;//用来表示存放命令数组的下标
char *argv[32];//用来存放命令的字符串数组


//处理用户输入的字符串
//如果是几个命令的组合的话(ls -l)
//这样的话,就将ls和-l分割成两个字符串分别放入如argv中。
int param(char *buff)
{
        argc = 0;
        if(buff == NULL)
                return -1;
        char* ptr = buff;//记录的是从键盘上输入的字符串的首地址
        char *tmp = ptr;//记录每个字符串的起始位置
        while(*ptr != '\0')
        {
                int status = 0;//用来表示是否执行了下面的while循环

                if(*ptr == ' ')//如果遇到的是空格的话
                {
                            //将这个空格字符变成一个'\0',表示空格前面的字符串为一个独立的字符
                            //比如"ls -l" ----> "ls\0""-l"将他们分成两个字符串来存放。
                        *ptr = '\0';
                        argv[argc] = tmp;
                        tmp = ptr + 1;//然后让tmp继续指向空格后的第一个字符
                        argc++;
                        while(*++ptr == ' ')//如果又连续空格的话,直接跳过空格,直到下一个是字符为止
                        {
                                tmp++;
                                status = 1;
                        }
                }
                if(status == 0)//如果执行了上面的while循环的话,代表ptr现在指向的是一个字符,所以不用再次移动,如果没有执行while循环的话,代表还在字符串中,继续向后遍历。
                        ptr++;
        }
        if(tmp != '\0')//将最后一个的字符串放入到字符数组中,比如ls经过上面的判断并没有将ls放入到字符串数组中
                                              
        {
                argv[argc] = tmp;
                argc++;
        }
        argv[argc] = NULL;//如果将命令解析完成之后的话,将数组的下一个位置置空,代表命令字符串的结束。
        return 0;
}
//用来执行字符串数组中的命令
int exec_cmd()
{
        int pid = 0;
        pid = fork();
        if(pid < 0)
        {
                exit(0);
        }
//在子进程中进行程序替换。
        else if(pid == 0)
        {
                execvp(argv[0], argv);
                exit(0);
        }

//父进程在这里等待子进程的退出
        int statu;
        wait(&statu);
//判断代码是否是运行完毕之后退出
        if(WIFEXITED(statu))
        {
//将子进程的退出码,转换为文本信息打印
                printf("%s\n", strerror(WEXITSTATUS(statu)));

        }
        return 0;
}
int main()
{
        //1.获取终端输入
        //2.按照空格解析
        //3.创建一个子进程
        //      在子进程中进行程序替换,让子进程去运行命令
        //4.等待子进程退出然后父进程释放子进程的资源
        while(1)
        {
                printf("Myshell->");
                char buff[1024] = {0};
                fflush(stdout);//用来刷新缓冲区的
                if(scanf("%[^\n]%*c", buff)!=1)
                        getchar();
                param(buff);
                exec_cmd();
        }
        return 0;
}
                                   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值