我有一个父进程,该进程分叉出子进程来执行execv()。
我需要将execv()输出到标准输出(stdout)并显示在屏幕上,同时将其复制到日志文件中。
如何将相同的输出写入stdout和文件中,而不使用管道(pipes)或tees?
如果您不想使用Tee,可以在写入数据之前先将其写入文件,然后将其发送到标准输出。
您应该编写一个记录函数来为您完成此操作,使其更加简洁。
您可以完全在程序内部完成此操作,但仍需要使用匿名管道作为pipe()
系统调用创建的。
基本上,您需要一个子进程执行与tee
相当的操作,这很容易实现:
int child_pipe[2];
pid_t pid_exec_child, pid_output_child;
pipe(child_pipe);
pid_exec_child = fork();
if (pid_exec_child == 0)
{
dup2(child_pipe[1], STDOUT_FILENO);
close(child_pipe[0]);
close(child_pipe[1]);
execve(/* ... */);
_exit(127);
}
close(child_pipe[1]);
pid_output_child = fork();
if (pid_output_child == 0)
{
/* This child just loops around, reading from the other child and writing everything
* to both stdout and the log file. */
int logfd = open("logfile", O_WRONLY);
char buffer[4096];
ssize_t nread;
while ((nread = read(child_pipe[0], buffer, sizeof buffer) != 0)
{
size_t nwritten_total;
ssize_t nwritten;
if (nread < 0)
{
if (errno == EINTR)
continue;
perror("read");
_exit(1);
}
/* Copy data to stdout */
nwritten_total = 0;
while (nwritten_total < nread)
{
nwritten = write(STDOUT_FILENO, buffer + nwritten_total, nread - nwritten_total);
if (nwritten < 0)
{
if (errno == EINTR)
continue;
perror("write(stdout)");
_exit(2);
}
nwritten_total += nwritten;
}
/* Copy data to logfile */
nwritten_total = 0;
while (nwritten_total < nread)
{
nwritten = write(logfd, buffer + nwritten_total, nread - nwritten_total);
if (nwritten < 0)
{
if (errno == EINTR)
continue;
perror("write(logfile)");
_exit(3);
}
nwritten_total += nwritten;
}
}
_exit(0);
}
close(child_pipe[0]);
/* Parent continues here */
tee
可能会更容易...(需要注意的是,子进程使用_exit()
,因为它们从父进程继承了标准I/O状态)。您可以使用dup2()
函数 - 此链接提供了一个示例
fork
命令的纯逻辑解决方案:http://www.linuxforums.org/forum/linux-programming-scripting/69391-redirect-stdout-file.html#post363639 - DVK另外,你可以使用 fifo(命名管道)。 mkfifo my.fifo; 在 execv 中:程序 > my.fifo; 然后像普通文件一样打开 fifo 并从中读取。这样你就可以解析标准输出,但是它有共享访问的一些小缺点。
tee
”回复。考虑编辑以明确您希望在内部执行此操作... - dmckee --- ex-moderator kitten