나는 몇 가지 프로그램을 결합하려고 노력하고 있습니다 (추가 포함을 무시하십시오. 이는 진행중인 작업입니다).
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
반복 프로그램의 소스는 다음과 같습니다.
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
inline std::string readline(int fd, const size_t len, const char delim = '\n')
{
std::string result;
char c = 0;
for(size_t i=0; i < len; i++)
{
const int read_result = read(fd, &c, sizeof(c));
if(read_result != sizeof(c))
break;
else
{
result += c;
if(c == delim)
break;
}
}
return result;
}
int main(int argc, char ** argv)
{
constexpr int max_events = 10;
const int fd_stdin = fileno(stdin);
if (fd_stdin < 0)
{
std::cerr << "#Failed to setup standard input" << std::endl;
return -1;
}
/* General poll setup */
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1) perror("epoll_create1: ");
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd_stdin;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_stdin, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd_stdin << " failed: " << strerror(errno) << std::endl;
}
if (argc > 1)
{
for (int i = 1; i < argc; i++)
{
const char * filename = argv[i];
const int fd = open(filename, O_RDONLY);
if (fd < 0)
std::cerr << "#Error opening file " << filename << ": error #" << errno << ": " << strerror(errno) << std::endl;
else
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd << "(" << filename << ") failed: " << strerror(errno) << std::endl;
else std::cerr << "Added fd " << fd << " (" << filename << ") to epoll!" << std::endl;
}
}
}
struct epoll_event events[max_events];
while(int event_count = epoll_wait(epoll_fd, events, max_events, -1))
{
for (int i = 0; i < event_count; i++)
{
const std::string line = readline(events[i].data.fd, 512);
if(line.length() > 0)
std::cout << line << std::endl;
}
}
return 0;
}
나는 이것을 보았다 :
- 방금 파이프를 사용하면
./repeat
모든 것이 의도 한대로 작동합니다. - 방금 프로세스 대체를 사용하면 모든 것이 의도 한대로 작동합니다.
- 프로세스 대체를 사용하여 pv를 캡슐화하면 모든 것이 의도 한대로 작동합니다.
- 그러나 특정 구성을 사용하면 stdin에서 데이터 (개별 문자)가 손실되는 것처럼 보입니다!
나는 다음을 시도했다.
- 모든 프로세스 사이
pv
에서./repeat
사용 하고 파이프에서 버퍼링을 비활성화하려고 시도했지만stdbuf -i0 -o0 -e0
작동하지 않는 것 같습니다. - 설문 조사를 위해 epoll을 교체했지만 작동하지 않습니다.
pv
와./repeat
with 사이의 스트림을tee stream.csv
보면 올바르게 보입니다.- 나는
strace
무슨 일이 있었는지 보았고, 예상대로 단일 바이트 읽기가 많으며 데이터가 누락되었음을 보여줍니다.
무슨 일인지 궁금 하신가요? 아니면 더 조사하기 위해 무엇을 할 수 있습니까?
<(...)
? 보다 좋은 방법이<( 0<&- ...)
있습니까?