管道execvp linux命令从孩子到父进程

发布于 2025-01-25 06:09:02 字数 1167 浏览 3 评论 0原文

我尝试用C语言编写一个程序,该程序在输入中采用简单的Linux命令,例如“ LS /Home”。 此命令在子进程中使用“ ExecVP”执行,并将其发送到要在屏幕上显示的父进程。

我的问题是程序正在运行,没有显示任何内容,并且不要回馈提示。我必须用“ ctrl + c”退出。

问题在时循环还是我的管道无处可发送我的命令?

感谢您的反馈

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>

int main(int argc, char* argv[])
{
        int     fd[2];
        int   pid;

        pipe(fd);
        
        if((pid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(pid == 0)
        {
                close(fd[0]);

            dup2(fd[1], STDOUT_FILENO);

            close(fd[1]);

            execvp(argv[1], &argv[1]);
        }
        else
        {
                close(fd[1]);

            dup2(fd[0], STDIN_FILENO);
            close(fd[0]);
            char result;
            while(read(fd[0], &result, sizeof(result) > 0))
            {
                write(fd[1], &result, sizeof(result));
            }
            wait(NULL);
        }
    close(fd[1]); 
    close(fd[0]);
    return(0);
}

I try to write a program in C language that takes a simple Linux command in input like "ls /home".
This command is executed in child process with "execvp" and sent to the parent process to be displayed on the screen..

My problem is that the program is running and display nothing and don't give back the prompt. I have to quit with "ctrl + C".

Is the problem in the while loop or my pipe send my command nowhere?

Thanks for your feedback

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>

int main(int argc, char* argv[])
{
        int     fd[2];
        int   pid;

        pipe(fd);
        
        if((pid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(pid == 0)
        {
                close(fd[0]);

            dup2(fd[1], STDOUT_FILENO);

            close(fd[1]);

            execvp(argv[1], &argv[1]);
        }
        else
        {
                close(fd[1]);

            dup2(fd[0], STDIN_FILENO);
            close(fd[0]);
            char result;
            while(read(fd[0], &result, sizeof(result) > 0))
            {
                write(fd[1], &result, sizeof(result));
            }
            wait(NULL);
        }
    close(fd[1]); 
    close(fd[0]);
    return(0);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

骷髅 2025-02-01 06:09:03

父母中,读取循环有问题。 前者相比

while(read(fd[0], &result, sizeof(result) > 0))

while(read(fd[0], &result, sizeof(result)) > 0)

,在您的程序中,使用了比较sizeof(result)&gt的结果。 0作为缓冲区的 size ,并且只要读取返回非零值。

请注意,结果charsizeof(char) is 保证 be 1

1&gt; 01,恰好是缓冲区的大小,因此部分工作。循环将继续发生错误(-1),并将继续尝试编写输出。

它还试图从fd [0]中读取,该>在

dup2(fd[0], STDIN_FILENO);
close(fd[0]);

不需要此重复后关闭。

另外,

write(fd[1], &result, sizeof(result));

正在尝试将输出写回管道。也就是说,父母较早关闭了此文件描述符(关闭(FD [1]);)。

请注意关闭(FD [1]); else> else 块是多余的(冗余关闭可以是更复杂的程序中的错误来源)。


儿童中,您应该处理execvp失败的事件,因为如果功能成功,它将永远不会返回。 execvp在失败状态下运行的任何预期运行(在您的程序中,即Else Block之后的行)。


粗略的示例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int fd[2];
    pid_t pid;

    if (argc < 2) {
        fprintf(stderr, "too few arguments\n");
        exit(EXIT_FAILURE);
    }

    if (-1 == pipe(fd)) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if (-1 == (pid = fork())) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {
        /* child */
        close(fd[0]);
        dup2(fd[1], STDOUT_FILENO);
        close(fd[1]);

        argv++;

        execvp(*argv, argv);
        perror("execvp");
        exit(EXIT_FAILURE);
    }

    /* parent */
    char result;

    close(fd[1]);

    while (read(fd[0], &result, 1) > 0)
        write(STDOUT_FILENO, &result, 1);

    close(fd[0]);
    wait(NULL);
}

In the parent, the read loop has problems. Compare

while(read(fd[0], &result, sizeof(result) > 0))

to

while(read(fd[0], &result, sizeof(result)) > 0)

The former, in your program, is using the result of the comparison sizeof(result) > 0 as the size of the buffer, and looping as long as read returns a nonzero value.

Note that result is a char, and sizeof (char) is guaranteed to be 1.

1 > 0 is 1, which just happens to be the size of your buffer, so this partially works. The loop will continue on error (-1) though, and will continue to attempt writing output.

It is also trying to read from fd[0], which was closed after

dup2(fd[0], STDIN_FILENO);
close(fd[0]);

This duplication is not needed.

Additionally,

write(fd[1], &result, sizeof(result));

is attempting to write the output back into the pipe. That said, the parent closed this file descriptor earlier (close(fd[1]);).

Note the close(fd[1]); outside of the else block is redundant (and redundant closes can be a source of bugs in more complex programs).


In the child, you should handle the event that execvp fails, because if the function succeeds, it never returns. Anything expected to run after execvp is operating in a failure state (in your program, that is the lines after the else block).


A cursory example:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int fd[2];
    pid_t pid;

    if (argc < 2) {
        fprintf(stderr, "too few arguments\n");
        exit(EXIT_FAILURE);
    }

    if (-1 == pipe(fd)) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if (-1 == (pid = fork())) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {
        /* child */
        close(fd[0]);
        dup2(fd[1], STDOUT_FILENO);
        close(fd[1]);

        argv++;

        execvp(*argv, argv);
        perror("execvp");
        exit(EXIT_FAILURE);
    }

    /* parent */
    char result;

    close(fd[1]);

    while (read(fd[0], &result, 1) > 0)
        write(STDOUT_FILENO, &result, 1);

    close(fd[0]);
    wait(NULL);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文