I am using R's pipe()
function to capture output from a shell command, but I would also like to get the exit code from the command.
I know that I could use system2
here, but I need the advantage of a pipe i.e. the ability to process output in a streaming fashion.
I am considering writing my own library to wrap the popen()
and pclose()
C functions to take advantage of the fact that pclose()
returns the exit status, but maybe this can be avoided.
Any suggestions? Thanks!
Note
There are certainly ways to do this with temporary files, named pipes, etc but I would ideally like to avoid these workarounds. I am willing to compile a shared library with an R->C function in it (and I'm even willing to copy-paste part of the R source code), but I'm not willing to rebuild R.
Update
I started reading through the R source code and found the unchecked pclose call:
in src/main/connections.c
:
static void pipe_close(Rconnection con)
{
pclose(((Rfileconn)(con->private))->fp);
con->isopen = FALSE;
}
I tried going forward with the approach of implementing an R_pclose
C function that duplicates the R code for close()
but saves this return value. I unfortunately ran into this static variable in src/main/connections.c
static Rconnection Connections[NCONNECTIONS];
Since I'd have to run objcopy --globalize-symbol=Connections libR.so /path/to/my/libR.so
anyway to access the variable, it looks like my best solution is to rebuild R with my own patch to capture the pclose return value.
Ugly hack: you can wrap your command call into a small shell script which writes the exit code of its child to some temporary file. So when the stream has ended, you could wait until that file has non-zero size, then read the status from there. I hope someone comes up with a better solution, but at least this is a kind of solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With