| tee(2) | System Calls Manual | tee(2) |
НАИМЕНОВАНИЕ¶
tee - повторяет содержимое канала
БИБЛИОТЕКА¶
Стандартная библиотека языка C (libc, -lc)
ОБЗОР¶
#define _GNU_SOURCE /* см. feature_test_macros(7) */ #include <fcntl.h>
ssize_t tee(int fd_in, int fd_out, size_t size, unsigned int flags);
ОПИСАНИЕ¶
tee() duplicates up to size bytes of data from the pipe referred to by the file descriptor fd_in to the pipe referred to by the file descriptor fd_out. It does not consume the data that is duplicated from fd_in; therefore, that data can be copied by a subsequent 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 устанавливается в соответствующее значение.
ОШИБКИ¶
СТАНДАРТЫ¶
Linux.
ИСТОРИЯ¶
Linux 2.6.17, glibc 2.5.
ПРИМЕЧАНИЯ¶
Концептуально, 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 <sys/types.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int fd;
ssize_t size, ssize;
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);
}
for (;;) {
/*
* tee stdin to stdout.
*/
size = tee(STDIN_FILENO, STDOUT_FILENO,
INT_MAX, SPLICE_F_NONBLOCK);
if (size < 0) {
if (errno == EAGAIN)
continue;
perror("tee");
exit(EXIT_FAILURE);
}
if (size == 0)
break;
/*
* Consume stdin by splicing it to a file.
*/
while (size > 0) {
ssize = splice(STDIN_FILENO, NULL, fd, NULL,
size, SPLICE_F_MOVE);
if (ssize < 0) {
perror("splice");
exit(EXIT_FAILURE);
}
size -= ssize;
}
}
close(fd);
exit(EXIT_SUCCESS);
}
СМОТРИТЕ ТАКЖЕ¶
ПЕРЕВОД¶
Русский перевод этой страницы руководства разработал(и) Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.
| 17 мая 2025 г. | Справочные страницы Linux (невыпущенные) |