Why do I seem to lose data using this bash pipe construction?Using data read from a pipe instead than from a...
How to avoid typing 'git' at the begining of every Git command
How do you play "tenth" chords on the guitar?
Convert only certain words to lowercase
Wizard clothing for warm weather
How (un)safe is it to ride barefoot?
Why isn't Bash trap working if output is redirected to stdout?
Do you need to let the DM know when you are multiclassing?
Rail-to-rail op-amp only reaches 90% of VCC, works sometimes, not everytime
If I had a daughter who (is/were/was) cute, I would be very happy
How to get depth and other lengths of a font?
The origin of the Russian proverb about two hares
Can I use 220v outlets on a 15 amp breaker and wire it up as 110v?
What is Gilligan's full Name?
Why do radiation hardened IC packages often have long leads?
What do you call the action of "describing events as they happen" like sports anchors do?
Oil draining out shortly after turbo hose detached/broke
What plausible reason could I give for my FTL drive only working in space
How to befriend someone who doesn't like to talk?
If the pressure inside and outside a balloon balance, then why does air leave when it pops?
Assigning function to function pointer, const argument correctness?
As easy as Three, Two, One... How fast can you go from Five to Four?
If absolute velocity does not exist, how can we say a rocket accelerates in empty space?
Is there a DSLR/mirorless camera with minimal options like a classic, simple SLR?
YA book about blind creatures that live underground and take kid's eyes
Why do I seem to lose data using this bash pipe construction?
Using data read from a pipe instead than from a file in command optionsWhy doesn't grep using pipe work here?using “ifne” in Bash pipeWhy does process substitution result in a file called /dev/fd/63 which is a pipe?How does Bash pipe large amounts of data?Why doesn't this tee with process substitution produce the 1st and chosen lines?What happens with “$0” when you pipe data to bashWhy process substitution is faster than pipe in this case?Is this bash argument substitution?Using bash script to pipe breakpoints to debugger prompt
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I am trying to combine a few programs like so (please ignore any extra includes, this is heavy work-in-progress):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Where the source of the repeat program looks as follows:
#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;
}
I noticed this:
- When I just use the pipe to
./repeat
, everything works as intended. - When I just use the process substitution, everything works as intended.
- When I encapsulate pv using process substitution, everything works as intended.
- However, when I use the specific construction, I appear to lose data (individual characters) from stdin!
I have tried the following:
- I have tried to disable buffering on the pipe between
pv
and./repeat
usingstdbuf -i0 -o0 -e0
on all processes, but that doesn't seem to work. - I have swapped epoll for poll, doesn't work.
- When I look at the stream between
pv
and./repeat
withtee stream.csv
, this looks correct. - I used
strace
to see what was going on, and I see lots of single-byte reads (as expected) and they also show that data is going missing.
I wonder what is going on? Or what I can do to investigate further?
linux bash pipe c++ process-substitution
New contributor
add a comment |
I am trying to combine a few programs like so (please ignore any extra includes, this is heavy work-in-progress):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Where the source of the repeat program looks as follows:
#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;
}
I noticed this:
- When I just use the pipe to
./repeat
, everything works as intended. - When I just use the process substitution, everything works as intended.
- When I encapsulate pv using process substitution, everything works as intended.
- However, when I use the specific construction, I appear to lose data (individual characters) from stdin!
I have tried the following:
- I have tried to disable buffering on the pipe between
pv
and./repeat
usingstdbuf -i0 -o0 -e0
on all processes, but that doesn't seem to work. - I have swapped epoll for poll, doesn't work.
- When I look at the stream between
pv
and./repeat
withtee stream.csv
, this looks correct. - I used
strace
to see what was going on, and I see lots of single-byte reads (as expected) and they also show that data is going missing.
I wonder what is going on? Or what I can do to investigate further?
linux bash pipe c++ process-substitution
New contributor
add a comment |
I am trying to combine a few programs like so (please ignore any extra includes, this is heavy work-in-progress):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Where the source of the repeat program looks as follows:
#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;
}
I noticed this:
- When I just use the pipe to
./repeat
, everything works as intended. - When I just use the process substitution, everything works as intended.
- When I encapsulate pv using process substitution, everything works as intended.
- However, when I use the specific construction, I appear to lose data (individual characters) from stdin!
I have tried the following:
- I have tried to disable buffering on the pipe between
pv
and./repeat
usingstdbuf -i0 -o0 -e0
on all processes, but that doesn't seem to work. - I have swapped epoll for poll, doesn't work.
- When I look at the stream between
pv
and./repeat
withtee stream.csv
, this looks correct. - I used
strace
to see what was going on, and I see lots of single-byte reads (as expected) and they also show that data is going missing.
I wonder what is going on? Or what I can do to investigate further?
linux bash pipe c++ process-substitution
New contributor
I am trying to combine a few programs like so (please ignore any extra includes, this is heavy work-in-progress):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Where the source of the repeat program looks as follows:
#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;
}
I noticed this:
- When I just use the pipe to
./repeat
, everything works as intended. - When I just use the process substitution, everything works as intended.
- When I encapsulate pv using process substitution, everything works as intended.
- However, when I use the specific construction, I appear to lose data (individual characters) from stdin!
I have tried the following:
- I have tried to disable buffering on the pipe between
pv
and./repeat
usingstdbuf -i0 -o0 -e0
on all processes, but that doesn't seem to work. - I have swapped epoll for poll, doesn't work.
- When I look at the stream between
pv
and./repeat
withtee stream.csv
, this looks correct. - I used
strace
to see what was going on, and I see lots of single-byte reads (as expected) and they also show that data is going missing.
I wonder what is going on? Or what I can do to investigate further?
linux bash pipe c++ process-substitution
linux bash pipe c++ process-substitution
New contributor
New contributor
edited 1 hour ago
muru
39k594169
39k594169
New contributor
asked 1 hour ago
Roel BaardmanRoel Baardman
1111
1111
New contributor
New contributor
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
epoll() or poll() returning with E/POLLIN will only tell you that a single read() may not block.
Not that you will be able to do a lot of one byte read()s up to a newline, as you do.
I say may because a read() after epoll() returned with E/POLLIN may still block.
Your code will also try to read past EOF, and completely ignores any read() errors.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f523929%2fwhy-do-i-seem-to-lose-data-using-this-bash-pipe-construction%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
epoll() or poll() returning with E/POLLIN will only tell you that a single read() may not block.
Not that you will be able to do a lot of one byte read()s up to a newline, as you do.
I say may because a read() after epoll() returned with E/POLLIN may still block.
Your code will also try to read past EOF, and completely ignores any read() errors.
add a comment |
epoll() or poll() returning with E/POLLIN will only tell you that a single read() may not block.
Not that you will be able to do a lot of one byte read()s up to a newline, as you do.
I say may because a read() after epoll() returned with E/POLLIN may still block.
Your code will also try to read past EOF, and completely ignores any read() errors.
add a comment |
epoll() or poll() returning with E/POLLIN will only tell you that a single read() may not block.
Not that you will be able to do a lot of one byte read()s up to a newline, as you do.
I say may because a read() after epoll() returned with E/POLLIN may still block.
Your code will also try to read past EOF, and completely ignores any read() errors.
epoll() or poll() returning with E/POLLIN will only tell you that a single read() may not block.
Not that you will be able to do a lot of one byte read()s up to a newline, as you do.
I say may because a read() after epoll() returned with E/POLLIN may still block.
Your code will also try to read past EOF, and completely ignores any read() errors.
answered 39 mins ago
pizdelectpizdelect
1,265311
1,265311
add a comment |
add a comment |
Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.
Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.
Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.
Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f523929%2fwhy-do-i-seem-to-lose-data-using-this-bash-pipe-construction%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown