三通总是返回EINVAL

问题描述:

我想弄清楚如何正确使用tee。在我的申请中,tee总是因为某种原因返回EINVAL。我越来越绝望,并试图运行tee的手册页(例如:https://linux.die.net/man/2/tee)中列出的示例应用程序,以发现即使该示例代码始终会失败,例如:tee: Invalid argument,例如使用时如下所示:cat tee.c | ./tee tee.log 。任何想法为什么会发生?三通总是返回EINVAL

从die.net的示例代码:

#define _GNU_SOURCE 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <limits.h> 

int 
main(int argc, char *argv[]) 
{ 
    int fd; 
    int len, slen; 
    if (argc != 2) { 
     fprintf(stderr, "Usage: %s <file>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 
    fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); 
    if (fd == -1) { 
     perror("open"); 
     exit(EXIT_FAILURE); 
    } 
    do { 
     /* 
     * tee stdin to stdout. 
     */ 
     len = tee(STDIN_FILENO, STDOUT_FILENO, 
        INT_MAX, SPLICE_F_NONBLOCK); 
     if (len < 0) { 
      if (errno == EAGAIN) 
       continue; 
      perror("tee"); 
      exit(EXIT_FAILURE); 
     } else 
      if (len == 0) 
       break; 
     /* 
     * Consume stdin by splicing it to a file. 
     */ 
     while (len > 0) { 
      slen = splice(STDIN_FILENO, NULL, fd, NULL, 
          len, SPLICE_F_MOVE); 
      if (slen < 0) { 
       perror("splice"); 
       break; 
      } 
      len -= slen; 
     } 
    } while (1); 
    close(fd); 
    exit(EXIT_SUCCESS); 
} 

tee需要文件描述符,fd_infd_out的管。

您的调用不为第二个文件描述符提供管道,而是提供引用TTY的文件描述符。还注意,在手册页的示例具体地使用了尾随| cat

The example below implements a basic tee(1) program using the tee() system call. 
Here is an example of its use: 

    $ date |./a.out out.log | cat 
    Tue Oct 28 10:06:00 CET 2014 
    $ cat out.log 
    Tue Oct 28 10:06:00 CET 2014 

不使用的配管的文件描述符用于第二(或第一,对于这个问题的)参数将有资格获得EINVAL:

EINVAL fd_in or fd_out does not refer to a pipe; or fd_in and fd_out refer to 
     the same pipe.