是否可以将子进程的标准输出重定向到父进程中的另一个文件?

pxyaymoc  于 2022-10-23  发布在  Linux
关注(0)|答案(3)|浏览(210)

子进程运行一个bin文件,该文件由高通提供。子进程由我的父进程调用,父进程由我开发。
当子进程运行时,它总是在外壳命令中打印大量日志。
那么,我是否可以将高通的流出流从标准输出重定向到父进程中的另一个文件?
如你所知,推动高通更新这个bin文件几乎是不可能的。

yjghlzjz

yjghlzjz1#

这里的关键部分是POSIX函数dup2,它允许您基本上用另一个文件描述符替换一个文件描述符。如果您使用fork(而不是system),您实际上可以控制在fork和加载另一个可执行文件的exec*之间的子进程中发生的事情。


# include <cstdlib>

extern "C" {

# include <fcntl.h>

# include <unistd.h>

}

# include <stdexcept>

# include <iostream>

pid_t start_child(const char* program, const char* output_filename)
{
    pid_t pid = fork();
    if (pid < 0) {
        // fork failed!
        std::perror("fork");
        throw std::runtime_error("fork failed");
    } else if (pid == 0) {
        // This code runs in the child process.
        int output_fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC);
        if (output_fd < 0) {
            std::cerr << "Failed to open log file " << output_filename << ":"
                      << std::endl;
            std::perror("open");
            std::exit(1);
        }
        // Replace the child's stdout and stderr handles with the log file handle:
        if (dup2(output_fd, STDOUT_FILENO) < 0) {
            std::perror("dup2 (stdout)");
            std::exit(1);
        }
        if (dup2(output_fd, STDERR_FILENO) < 0) {
            std::perror("dup2 (stderr)");
            std::exit(1);
        }
        if (execl(program, program, (char*)nullptr) < 0) {
            // These messages will actually go into the file.
            std::cerr << "Failed to exec program " << program << ":"
                      << std::endl;
            std::perror("execl");
            std::exit(1);
        }
    }
    return pid;
}
iyr7buue

iyr7buue2#

对于POSIX来说,这是可能的,因为POSIX外壳可以做到这一点。对于POSIX,执行程序有两个步骤。首先使用fork克隆父进程以创建子进程。然后使子进程使用EXEC系列系统调用中的一个来执行所选程序,而不是父进程的程序。在这两个步骤之间,为子进程执行的代码可以执行其他操作,这将影响要执行的程序的环境。具体地说,代码可以打开要重定向到的文件的文件描述符,关闭标准输出文件描述符,然后将文件的文件描述符复制为用于标准输出的值(1)。

xsuvu9jc

xsuvu9jc3#

您可以创建自己的管道并将它们附加到子进程。
1.创建3个管道。他们将把孩子们的孩子换掉。
1.fork()
1.在子进程close()中,管道的父端。关闭stdin、stdout和stderr。
1.父进程close()管道的子端。
1.dup2()管道在子进程中结束,这些子进程旨在用作新的stdin、out、err
1.把孩子抱起来。
现在,您获得了从子对象到父对象中的管道的所有输出。当然,您需要从子进程的管道中读取数据,否则它将阻止对stdout/stderr的任何写入。为此,您可以使用select()poll()epoll()多路复用算法。
看见
https://linux.die.net/man/2/pipe
https://linux.die.net/man/2/dup2
https://linux.die.net/man/2/execve
https://linux.die.net/man/2/fork

相关问题