How to Capture the Output of System()

How to capture the output of system()

You could add a function knitr::system that masks base::system. Users could work with it like it was system::base, but the output can be captured by capture.output:

system <- function(...) {
stopifnot(!any(names(list(...)) %in% "intern"))
result <- base::system(..., intern = TRUE)
print(result)
}

I admit, that this is somewhat hacky, and to be honest, I'm not sure about possible side effects. But I think it could be worth a try.

Capture output of system command within a function in R

Here's a solution... But be warned, it works for me on Linux, might work on a Mac, and I doubt it works on Windows...

Create two Rcpp functions:

library(Rcpp)
cppFunction('void redir(){FILE* F=freopen("/tmp/capture.txt","w+",stdout);}')
cppFunction('void resetredir(){FILE* F=freopen("/dev/tty","w+",stdout);}')

The first will send everything to that file. The second will reset it. The problem is that interactively after the first you'll not be able to see anything. So beware...

So initially system2 sends to the console:

> system2("echo", "hello")
hello

But wrapping a call in redir/resetredir sends it to the file:

> redir(); system2("echo","hello world this time") ; resetredir()
> # prompt returns!

Now we have:

$ cat /tmp/capture.txt 
hello world this time

and if this is the output from some other package you'll have to read it in with R's file I/O routines.

The dodgy bit is the use of /dev/tty in the reset code - I'm not sure it works on a Mac or Windows. If you don't care about resetting the stdout then skip it, and just make sure you know how to quite R without seeing what you type. I'm also unsure if this will work in RStudio which probably has a different concept of the console....

Dynamically capture output of system command in Perl

If you're trying to 'capture' the output of a system call, then I would suggest the best approach is to use open and open a filehandle to your process:

my $pid = open ( my $process_output, '-|', "command" ); 

Then you can read $process_output exactly as you would a file handle (bear in mind it'll block if there's no IO pending).

while ( <$process_output> ) { 
print;
}

close ( $process_output );

You can 'fake' the behaviour of system via the waitpid system call:

 waitpid ( $pid, 0 ); 

This will 'block' your main program until the system call has completed.

Get system command output in C program

Ok, I was confused in my other answer. In any case, the philosophy in this answer is the same. You can use directly the popen function.

Then you have something like this:

int numOfCPU;
FILE *fp = popen("grep -c ^processor /proc/cpuinfo", "r");

fscanf(fp, "%d", &numOfCPU);
pclose(fp);

I hope it will be useful.

Getting output of a system command from stdout in C

You want to use popen. It returns a stream, like fopen. However, you need to close the stream with pclose. This is because pclose takes care of cleaning up the resources associated with launching the child process.

FILE *ls = popen("ls", "r");
char buf[256];
while (fgets(buf, sizeof(buf), ls) != 0) {
/*...*/
}
pclose(ls);

Capture the output of Perl's 'system()'

That's what backticks are for. From perldoc perlfaq8:

Why can't I get the output of a command with system()?

You're confusing the purpose of system() and backticks (``). system()
runs a command and returns exit status information (as a 16 bit value:
the low 7 bits are the signal the process died from, if any, and the
high 8 bits are the actual exit value). Backticks (``) run a command
and return what it sent to STDOUT.

my $exit_status   = system("mail-users");
my $output_string = `ls`;

See perldoc perlop for more details.

How do I execute a command and get the output of the command within C++ using POSIX?

#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>

std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}

Pre-C++11 version:

#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>

std::string exec(const char* cmd) {
char buffer[128];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!");
try {
while (fgets(buffer, sizeof buffer, pipe) != NULL) {
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}

Replace popen and pclose with _popen and _pclose for Windows.



Related Topics



Leave a reply



Submit