How to get linux command line output and output status in C ++

I want to get the output line of a Linux command, as well as the status of the command output in a C ++ program. I execute Linux commands in my application.

for example: Command:

rmdir abcd

Command output line:

rmdir: failed to delete `abcd ': no ​​such file or directory

Team Status:

1 (This means the command was crashing)

I tried to use the Linux system() function, which gives the status of the output, and the popen() function, which gives me the output line of the command, but none of the functions gives me the output line and the status of the output of the Linux command.

+6
source share
5 answers

The output line is in standard output or standard error descriptor (1 or 2, respectively).

You should redirect these streams (take a look at the dup and dup2 functions) to the place where you can read them (e.g. POSIX pipe ).

In C, I would do something like this:

 int pd[2]; int retValue; char buffer[MAXBUF] = {0}; pipe(pd); dup2(pd[1],1); retValue = system("your command"); read(pd[0], buffer, MAXBUF); 

Now you have (part) of your output in the buffer and the return code in retValue.

Alternatively, you can use the function from exec (i.e. execve ) and get the return value using wait or waitpid .

Update: this will redirect only standard output. To redirect the standard error, use dup2(pd[1],1) .

+7
source

The easiest solution is to use system and redirect the standard error and standard error to a temporary file that you can delete later.

+3
source

Unfortunately, in C on Linux there is no simple and easy way to do this. Here is an example of how to correctly read / stdout / stdr / stdin for a child process.

And if you want to get the exit code, you should use waitpid (a full example is given at the bottom of the page provided):

 endID = waitpid(childID, &status, WNOHANG|WUNTRACED); 

Now you just need to join these two together :)

There is also a free, free book called Advanced L inux Programming (ALP) containing detailed information on these available issues here .

+2
source

Based on the answer of Peter Zierhoffer above, here is a function that does just that, and also restores the original state of stdout and stderr.

 // Execute command <cmd>, put its output (stdout and stderr) in <output>, // and return its status int exec_command(string& cmd, string& output) { // Save original stdout and stderr to enable restoring int org_stdout = dup(1); int org_stderr = dup(2); int pd[2]; pipe(pd); // Make the read-end of the pipe non blocking, so if the command being // executed has no output the read() call won't get stuck int flags = fcntl(pd[0], F_GETFL); flags |= O_NONBLOCK; if(fcntl(pd[0], F_SETFL, flags) == -1) { throw string("fcntl() failed"); } // Redirect stdout and stderr to the write-end of the pipe dup2(pd[1], 1); dup2(pd[1], 2); int status = system(cmd.c_str()); int buf_size = 1000; char buf[buf_size]; // Read from read-end of the pipe long num_bytes = read(pd[0], buf, buf_size); if(num_bytes > 0) { output.clear(); output.append(buf, num_bytes); } // Restore stdout and stderr and release the org* descriptors dup2(org_stdout, 1); dup2(org_stderr, 2); close(org_stdout); close(org_stderr); return status; } 
+1
source

you can use the popen system call, it redirects the output to a file, and from the file you can redirect the output to a string. eg:

  char buffer[MAXBUF] = {0}; FILE *fd = popen("openssl version -v", "r"); if (NULL == fd) { printf("Error in popen"); return; } fread(buffer, MAXBUF, 1, fd); printf("%s",buffer); pclose(fd); 

For more information, read the man page for popen .

0
source

All Articles