2

我需要帮助才能使以下工作。我需要从 c++ 启动一个 bash 进程,这个 bash 进程需要接受来自 stdin 的输入并按照正常输出到 stdout。

从不同的过程中,我需要将命令写入标准输入,然后按照上面的方法在 bash 中实际执行,然后我对标准输出的结果感兴趣。

这是我迄今为止尝试过的,但输出对我来说根本没有意义......

        if (pipe(pipeBashShell)) {
            fprintf(stderr, "Pipe error!\n");
            exit(1);
        }

        if ((pipePId = fork()) == -1) {
            fprintf(stderr, "Fork error. Exiting.\n"); /* something went wrong */
            exit(1);
        }

        if (pipePId == 0) { //this is the child process
            dup2(pipeBashShell[0], STDIN_FILENO);
            dup2(pipeBashShell[1], STDOUT_FILENO);
            dup2(pipeBashShell[1], STDERR_FILENO);

            static char* bash[] = {"/bin/bash", "-i", NULL};
            if (execv(*bash, bash) == -1) {
                fprintf(stderr, "execv Error!");
                exit(1);
            }
            exit(0);
        } else {
            char buf[512];
            memset(buf, 0x00, sizeof(buf));
            sprintf(buf, "ls\n");
            int byteswritten = write(pipeBashShell[1], buf, strlen(buf));
            int bytesRead = read(pipeBashShell[0], buf, sizeof(buf));

            write(STDOUT_FILENO, buf, strlen(buf));
            exit(0);
        }

.

上述结果的输出如下:

' (main) bash:: command not found gerhard@gerhard-work-pc:~/workspaces/si/si$ gerhard orkspaces/si/si$ gerhard@gerhard-work-pc:~/workspa ....

我试图发送到 bash 的命令是“ls”,它应该给我一个目录列表

我在这里错过了什么吗?

4

1 回答 1

4

您已经创建了一个管道(有两端),并且您正在尝试将其用于双向通信——从您的主进程到 bash,反之亦然。为此,您需要两个单独的管道。

您连接文件描述符的方式使 bash 与自身对话——它将提示解释为它找不到的命令,然后将错误消息解释为后续命令。

编辑:

正确的设置如下:

  1. 准备两个管道:

    int parent2child[2], child2parent[2];
    pipe(parent2child);
    pipe(child2parent);
    
  2. fork()

  3. 在父进程中:

    close(parent2child[0]);
    close(child2parent[1]);
    // write to parent2child[1], read from child2parent[0]
    
  4. 在子进程中:

    close(parent2child[1]);
    close(child2parent[0]);
    dup2(parent2child[0], STDIN_FILENO);
    dup2(child2parent[1], STDOUT_FILENO);
    
于 2012-08-24T11:57:16.890 回答