मैं कुछ कार्यक्रमों को संयोजित करने की कोशिश कर रहा हूं (कृपया किसी भी अतिरिक्त को अनदेखा करें, यह भारी कार्य-प्रगति है):
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 को अतिक्रमण करता हूं, तो सब कुछ इच्छित तरीके से काम करता है।
- हालांकि, जब मैं विशिष्ट निर्माण का उपयोग करता हूं, तो मैं स्टड से डेटा (व्यक्तिगत वर्ण) खो देता हूं!
मैंने निम्नलिखित कोशिश की है:
- मैंने सभी प्रक्रियाओं के बीच
pv
और./repeat
उपयोग करने वाले पाइप पर बफरिंग को अक्षम करने की कोशिश कीstdbuf -i0 -o0 -e0
है, लेकिन यह काम नहीं करता है। - मैंने पोल के लिए एपोल को स्वैप किया है, काम नहीं करता है।
- जब मैं के बीच धारा को देखो
pv
और./repeat
साथtee stream.csv
, यह सही लग रहा है। - मैं
strace
देखता था कि क्या चल रहा है, और मुझे बहुत से सिंगल-बाइट रीड (जैसा कि अपेक्षित था) दिखाई देते हैं और वे यह भी दिखाते हैं कि डेटा गायब हो रहा है।
मुझे आश्चर्य है कि क्या चल रहा है? या आगे की जांच के लिए मैं क्या कर सकता हूं?
<(...)
? क्या इससे अच्छा कोई तरीका है<( 0<&- ...)
?