2014-12-04 70 views
0

我需要将stdoutstderr的子进程复制到多个文件。
据我所知,我可以使用tee(),但我还没有找到这方面的例子。 现在,只能将所有内容打印到stdout和stderr。 如何做到这一点?复制stdout和stderr从fork进程到文件

pid_t childId = fork(); 
    switch(childId){ 
    case -1: 
     perror("fork() error!\n"); 
     return; 
    case 0: 

     mysignal(SIGTTOU, SIG_DFL); 
     mysignal(SIGTTIN, SIG_DFL); 
     mysignal(SIGCHLD, SIG_DFL); 
     if(!background) 
      tcsetpgrp(cterm, getpid()); 
     setpgid(0, 0); 
     if (isWriter) close(pipefd[0]); 
     if (isReader!=-1) { 
      close(0); 
      dup(oldChannelOut); 
     } 

     if(isWriter){ 
      close(1); 
      dup(pipefd[1]); 
     } 
     //exec, if program is in current directory 
     execv(commandArgv[0], commandArgv); 
     int i = 0; 
     char buf[_POSIX_MAX_PATH]; 
     while(path[i] != NULL){ 
      buf[0] = '\0'; 
      strcat(buf, path[i]); 
      if(path[i][ strlen(path[i])-1 ] != '/'){ 
       buf[strlen(path[i])] = '/'; 
       buf[strlen(path[i])+1] = '\0'; 
      } 
      strcat(buf, commandArgv[0]); 
      execv(buf, commandArgv); 
      ++i; 
     } 
     fprintf(stderr,"\"%s\": command not found\n",commandArgv[0]); 
     exit(1); 

UPD:试图修改,不工作后。问题在哪里?

fdout=open("1", O_APPEND | O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 
fderr=open("2",O_APPEND | O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 
... 
case 0: 
if (isReader!=-1) { 
close(0); 
dup(oldChannelOut); 
} 
dup2(fdout, 1); 
dup2(fderr, 2); 
close(fdout); 
close(fderr); 
exec.... 
default: 
{ 

if(background) { 
addJob(&jobListStartB,childId,commandArgv,BACKGROUND); 
if (oldChannelOut != -1){ 
close(oldChannelOut); 
oldChannelOut = -1; 
} 
} 
else if(!background){ 
if (oldChannelOut != -1){ 

close(oldChannelOut); 
oldChannelOut = -1; 
} 
} 
+0

因此,派生进程的输出和错误将被写入到输出和错误,以及两个文件,对吧? – Deduplicator 2014-12-04 13:14:56

+0

它们必须是DUPLICATE到两个文件,而不是只写。 – 2014-12-04 13:24:38

+0

你是什么意思? – Deduplicator 2014-12-04 13:35:23

回答

0

使用teesplice写从手柄到多个其他处理数据:

// Needs at least two targets, sentinel is INVALID_HANDLE_VALUE 
int push_to_all(int source, ssize_t count, ...) { 
    va_list vl; 
    va_start(vl, count); 
    int target = va_arg(vl, int), next = va_arg(vl, int); 
    count = tee(source, target, count, SPLICE_F_NONBLOCK); 
    if(count <= 0) { va_end(vl); return count; } 
    while((target = next, next = va_arg(vl, int)) > 0) { 
     tee(source, target, count, 0); 
    va_end(vl); 
    return splice(source, 0, target, 0, count, 0); 
} 
+0

它可以帮助我吗?我必须做的事,复制stdout文件? – 2014-12-04 16:30:22

+0

这是一个从管道读取到您的子进程的函数,并将该数据写入任意数量的其他句柄。 – Deduplicator 2014-12-04 16:32:44

+0

我编辑了我的程序,但它不写入文件...请参阅upd。 – 2014-12-04 22:12:58