首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C- Piping和外部命令中创建外壳

在C- Piping和外部命令中创建外壳
EN

Stack Overflow用户
提问于 2021-07-08 00:20:06
回答 1查看 43关注 0票数 0

我正在尝试使用C创建一个小的shell,目前我正在尝试弄清楚管道和外部命令。即使在看了各种youtube视频后,我还是被困在了他们两个人身上。我指的是MAN甚至是Advanced Linux Programming

我可以改变什么来改进和使实现工作?

这是检查命令、args := tokenisation by whitespacecommLHS := will be used to store args before | and commRHS will be used to store args after |indexT refers to the number of arguments inputted的一部分

代码语言:javascript
复制
else if((check4pipe(args, commLHS, commRHS, indexT) != 0))
    {
        return runPipeComm(commLHS, commRHS);
        //fprintf(stderr, "%s: command not found\n", args[0]);
    }

这将执行外部命令

代码语言:javascript
复制
void externalCommands(char **args)
{
    // fork-plus-exec pattern 
    // https://www.percona.com/community-blog/2021/01/04/fork-exec-wait-and-exit/

    /*
        First we Fork
        Then we Exec
        Then we Wait
        Then we Exit
    */
    int status;
    
    pid_t pip = fork();

    if (pip == -1) 
    {
        perror("Error - fork()");
    }
    else if (pip == 0) 
    {   
        //If PID is the child process
        //Launches the process.
        
        if (execvp(args[0], args) < 0) 
        {
            perror("Error - execvp()");
        }
    }
    else 
    { //If PID is the parent process.
        //Waits for the child process and returns exit code if waitpid() is successful.
            if(waitpid(pip, &status, WUNTRACED) == -1)
            {
                perror("Error occured during waitpi");
            }
            else
            {   
                //set_exitcode(status); //Sets the exitcode environment variable.
            }
    }
    
}

这是为了在标记化之后检查用户输入的参数中的|。

代码语言:javascript
复制
int check4pipe(char **args, char **pipeLHS, char **pipeRHS, int indexT)
{
    bool foundPipe = false;

    for(int i = 0; i < indexT; i++)
    {
        if(strcmp(args[i], "|") == 0)
        {
            foundPipe = true;

            memcpy(pipeLHS, args, (i+1) * sizeof(char*));
            pipeLHS[i] = NULL;

            memcpy(pipeLHS, args+(i+1), ((indexT-i)+1) * sizeof(char*));
            pipeRHS[i]= NULL;
        }
        else
        {
            continue;
        }
    }

    if(foundPipe == true)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

这将运行管道命令

代码语言:javascript
复制
int runPipeComm(char **commLHS, char **commRHS)
{
    int userPipe[2];
    
    pid_t pip1; // Pipe ID 1
    pid_t pip2; // Pipe ID 2

    if(pipe(userPipe) < 0)
    {
        perror("Error Occurred while piping: ");
    }

    // Start Process 
    pip1 = fork();

    if(pip1 == -1)
    {
        perror("Error Occurred while forking: ");
    }
    else if(pip1 == 0)
    {
        dup2(userPipe[1], STDOUT_FILENO);
        close(userPipe[1]);

        //run

        exit(0);
    }
    else
    {
        pip2 = fork();

        if(pip2 == -1)
        {
            perror("Error Occurred while forking: ");
        }
        else if(pip2 == 0)
        {
            dup2(userPipe[0], STDOUT_FILENO);
            close(userPipe[1]);

            //run

            exit(0);
        }
        else
        {
            close(userPipe[0]);
            close(userPipe[1]);

            wait(NULL);
            wait(NULL);
        }
    }

    return 1;
}
EN

回答 1

Stack Overflow用户

发布于 2021-07-09 03:21:22

在程序中复制代码片段时,您忘记了更改某些内容。

错误:

代码语言:javascript
复制
            memcpy(pipeLHS, args+(i+1), ((indexT-i)+1) * sizeof(char*));
            pipeRHS[i]= NULL;

右图:

代码语言:javascript
复制
            memcpy(pipeRHS, args+(i+1), (indexT-(i+1)) * sizeof (char*));
            pipeRHS[indexT-(i+1)] = NULL;

错误:

代码语言:javascript
复制
            dup2(userPipe[0], STDOUT_FILENO);
            close(userPipe[1]);

右图:

代码语言:javascript
复制
            dup2(userPipe[0], STDIN_FILENO);
            close(userPipe[0]);

在第一个//run行之后,添加缺少的

代码语言:javascript
复制
        execvp(*commLHS, commLHS);
        perror("Error - execvp()");

在第二个//run行之后,添加缺少的

代码语言:javascript
复制
            execvp(*commRHS, commRHS);
            perror("Error - execvp()");

最后,在父进程中必须关闭管道的写入端,因此将close()移到那里:

代码语言:javascript
复制
        close(userPipe[1]);
        pip2 = fork();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68289675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档