TEE - Linux手册页

时间:2019-08-20 17:59:33  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

tee-复制管道内容

语法

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <fcntl.h>

ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);

说明

tee()从文件描述符fd_in引用的管道到文件描述符fd_out引用的管道最多复制len个字节的数据。它不使用从fd_in复制的数据;因此,该数据可以由后续的splice(2)复制。

标志是一个位掩码,由以下零个或多个以下值组成或:

SPLICE_F_MOVE
当前对tee()无效;参见splice(2)。
SPLICE_F_NONBLOCK
不要阻塞I / O;有关更多详细信息,请参见splice(2)。
SPLICE_F_MORE
当前对tee()无效,但可能会在将来实施;参见splice(2)。
SPLICE_F_GIFT
未用于tee();请参见vmsplice(2)。

返回值

成功完成后,tee()返回在输入和输出之间重复的字节数。返回值为0表示没有数据要传输,也没有意义进行阻塞,因为没有写入器连接到fd_in所指管道的写入端。

发生错误时,tee()返回-1,并且将errno设置为指示错误。

错误说明

EAGAIN
在标志中指定了SPLICE_F_NONBLOCK或已将文件描述符之一标记为非阻塞(O_NONBLOCK),并且该操作将阻塞。
EINVAL
fd_in或fd_out不引用管道;或fd_in和fd_out引用同一管道。
ENOMEM
内存不足。

版本

tee()系统调用首先出现在Linux 2.6.17中;库支持已在2.5版中添加到glibc。

遵循规范

此系统调用是特定于Linux的。

备注

从概念上讲,tee()在两个管道之间复制数据。实际上,实际上并没有发生真正的数据复制:在幕后,tee()仅通过获取对输入的引用将数据分配给输出。

示例

下面的示例使用tee()系统调用实现一个基本的tee(1)程序。这是其用法示例:

$ 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

Program source

#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);
}

另外参见

splice(2),vmsplice(2),管道(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/