minishell【模拟 shell 基本功能】

思路

  1. 从标准输入当中读取数据(要执行的可执行程序)(fgets)
  2. 拆分可执行程序名称和命令行参数,标准输入当中读取到的内容第一个空格之前的数据是可执行程序名称,之后都为命令行参数(isspace)
  3. 创建子进程,子进程程序替换可执行程序(fork)
  4. 在子进程程序替换时间内,让父进程进行进程等待(execvp、waitpid)

代码实现

minishell.c

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h> 
char g_Command[1024];
int GetCommand()
{
    memset(g_Command, '\0', sizeof(g_Command));
    printf("[minishell@localhost]$ ");
    fflush(stdout);
    //要从标准输入中去读数据
    if(!fgets(g_Command, sizeof(g_Command) - 1, stdin))
    {
        printf("fgets error\n");
        return -1;
    }

    printf("g_Command = [%s]\n", g_Command);
    return 0;
}
int ExecCommand(char* argv[])
{
    if(argv[0] == NULL)
    {
        printf("ExecCommand error\n");
        return -1;
    }
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork");
        return -1;
    }
    else if(pid == 0)
    {
        //child
        execvp(argv[0], argv);
        exit(0);
    }
    else
    {
        //father
        waitpid(pid, NULL, 0);
    }
    return 0;
}
int DealCommand(char* command)
{
    if(!command || *command == '\0')
    {
        printf("command error\n");
        return -1;
    }
    int argc = 0;
    char* argv[32];
    //ls -l\n
    //argv[0] = "ls"
    //argv[1] = "-l"
    //var
    //strchr(char* str, int c);
    //123 456
    //char* 
    //strchr(str, ' ');
    while(*command)
    {
        if(!isspace(*command))
        {
            argv[argc] = command;
            argc++;
            while(!isspace(*command) && (*command != '\0'))
            {
                command++;
            }
            *command = '\0';
        }
        command++;
    }
    //防止一个未定义行为
    argv[argc] = NULL;
    for(int i = 0; i < argc; i++)
    {
        printf("[%d][%s]\n", i, argv[i]);
    }
    ExecCommand(argv);
    return 0;
}
int main()
{
    while(1)
    {
        if(GetCommand() == -1)
        {
            continue;
        }
        //处理我们所获得的命令
        DealCommand(g_Command);
    }
    return 0;
}

test.c

#include <stdio.h>
#include <unistd.h>
int main()
{
    char* argv[3];
    argv[0] = "ls";
    argv[1] = "-l";
    //argv[2] = NULL;
    execvp("ls", argv);
    printf("hahaha\n");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值