tee - повторяет
содержимое
канала
Standard C library (
libc,
-lc)
#define _GNU_SOURCE /* см. feature_test_macros(7) */
#include <fcntl.h>
ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
Вызов
tee()
повторяет
до
len байт
данных из
канала, на
который
указывает
файловый
дескриптор
fd_in в канал,
на который
указывает
файловый
дескриптор
fd_out. Он не
потребляет
данные,
копируемые
из
fd_in,
поэтому
эти данные
можно
копировать
последующим
вызовом
splice(2).
Аргумент
flags
представляет
собой
битовую
маску,
которая
составляется
логическим
сложением (OR)
следующих
значений:
- SPLICE_F_MOVE
- В данный
момент
никак не
влияет при
указании в
tee(); см. splice(2).
- SPLICE_F_NONBLOCK
- Не
блокировать
ввод-вывод;
подробности
в splice(2).
- SPLICE_F_MORE
- В данный
момент
никак не
влияет при
указании в
tee(), но это
может
измениться;
см. splice(2).
- SPLICE_F_GIFT
- Не
используется
для tee(); см.
vmsplice(2).
При
успешном
выполнении,
tee()
возвращает
количество
байт,
которые
были
повторены
из ввода в
выводе.
Возвращаемое
значение 0
означает,
что нет
данных для
передачи, и
блокировка
не имеет
смысла, так
как нет
процессов-писателей,
подключённых
к каналу
для записи,
на который
указывает
fd_in.
В случае
ошибки
tee()
возвращает
-1, а
errno
устанавливается
в
соответствующее
значение.
- EAGAIN
- В flags
указан SPLICE_F_NONBLOCK
или один из
файловых
дескрипторов
был
помечен
как
неблокирующий
( O_NONBLOCK), и
операция
вызвала бы
блокировку.
- EINVAL
- Значение
fd_in или fd_out не
указывает
на канал; fd_in
и fd_out
указывают
на один и
тот же
канал.
- ENOMEM
- Не
хватает
памяти.
The
tee() system call first appeared in Linux 2.6.17; library support was
added in glibc 2.5.
Данный
вызов есть
только в Linux.
Концептуально,
tee() копирует
данные
между
двумя
каналами. В
реальности,
данные не
копируются
на самом
деле:
внутри,
tee()
назначает
данные на
вывод
просто
схватывая
ссылку из
ввода.
В примере
далее
показана
простая
реализация
программы
tee(1) с
помощью
системного
вызова
tee().
Пример
использования:
$ 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
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int fd;
ssize_t len, slen;
if (argc != 2) {
fprintf(stderr, "Использование: %s <файл>\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);
}
for (;;) {
/*
* 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);
}
if (len == 0)
break;
/*
* Поглотить stdin, объединяя данные в файле.
*/
while (len > 0) {
slen = splice(STDIN_FILENO, NULL, fd, NULL,
len, SPLICE_F_MOVE);
if (slen < 0) {
perror("splice");
exit(EXIT_FAILURE);
}
len -= slen;
}
}
close(fd);
exit(EXIT_SUCCESS);
}
splice(2),
vmsplice(2),
pipe(7)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitry Bolkhovskikh
<
[email protected]>, Yuri Kozlov <
[email protected]> и
Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]