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;
}







2















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 using stdbuf -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 with tee 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?










share|improve this question









New contributor



Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


























    2















    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 using stdbuf -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 with tee 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?










    share|improve this question









    New contributor



    Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      2












      2








      2








      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 using stdbuf -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 with tee 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?










      share|improve this question









      New contributor



      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      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 using stdbuf -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 with tee 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






      share|improve this question









      New contributor



      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share|improve this question









      New contributor



      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share|improve this question




      share|improve this question








      edited 1 hour ago









      muru

      39k594169




      39k594169






      New contributor



      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      asked 1 hour ago









      Roel BaardmanRoel Baardman

      1111




      1111




      New contributor



      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




      New contributor




      Roel Baardman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.
























          1 Answer
          1






          active

          oldest

          votes


















          1














          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.






          share|improve this answer
























            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.










            draft saved

            draft discarded


















            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









            1














            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.






            share|improve this answer




























              1














              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.






              share|improve this answer


























                1












                1








                1







                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.






                share|improve this answer













                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.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 39 mins ago









                pizdelectpizdelect

                1,265311




                1,265311






















                    Roel Baardman is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                    Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                    Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...