0

I want to redirect the output from executing a command in the terminal to a string in c++. I dont want the command output to appear at all in the terminal because i am using an ncurses display. is there any way i can do this?

i am using a Linux terminal.

I have considered redirecting to a temp file then reading the contents of a file. But i would much prefer not to introduce tmp files. to clarify, i want to be able to do the following:

  1. echo "hello world" via execve
  2. redirect the output from the terminal to an std::string, so that it does not in fact show in the terminal at this stage.
  3. use printw function in ncurses to print the command output to an ncurses window

i am currently looking for possible implementations using features from termios.h and possibly dup2

my code looks like this:

std::string containerForOutput;


// some method which redicects execve into containerForOutput here

char cmd[100];
strcpy(cmd, "/usr/bin/");
strcat(cmd, argv[0]);

// execute the command using execve, but
// will not output to terminal after command is given
// and will instead store it in the string containerForOutput
int result = execve(cmd, argv, environ);
perror("Fallback Shell");

Using a stringstream did not work.

Tak Makoni
  • 467
  • 1
  • 4
  • 7
  • 1
    In which process is this `std::string` supposed to exist? And what is the relationship between *that* process and the process generating the data? Parent and child respectively? You should show the code you've written so far. – G.M. Mar 14 '20 at 11:47
  • Have a llok at [this](https://stackoverflow.com/a/10151286/4179302) post. – apalomer Mar 14 '20 at 11:57
  • 1
    https://stackoverflow.com/a/478960/1216776 – stark Mar 14 '20 at 12:16

1 Answers1

0

A good alternative is to use the pstream header file instead of execve, which creates a child process.

thanks to this post:

https://stackoverflow.com/a/10702464/5133238

Instead of using exec i capture the output and print it using the ncurses printw method:

  // run a process and create a streambuf that reads its stdout and stderr
  redi::ipstream proc("echo hello", redi::pstreams::pstdout | redi::pstreams::pstderr);
  std::string line;
  // read child's stdout
  while (std::getline(proc.out(), line)) {
   // the output is captured line by line here
   // so that i can do what i want with it
    printw(line.c_str());
    printw("\n");
  }

  // if reading stdout stopped at EOF then reset the state:
  if (proc.eof() && proc.fail()) {
    proc.clear();
  }
  // read child's stderr
  while (std::getline(proc.err(), line)) {
   // error message is captured line by line here
   // so that i can do what i want with it.
    printw(line.c_str());
    printw("\n");
  }

pstreams here: http://pstreams.sourceforge.net/

Tak Makoni
  • 467
  • 1
  • 4
  • 7