How to read shell output into a variable

Dear ROOT folks

I am wondering how I might read shell output straight into a variable. (I have a GUI where I need to display some values such as temperature etc. that I can grab with a shell command). For the sake of example, let’s say I want to display seconds of the current time which I can get from the “date” command. For the time being, I would do that by having the shell write the number into a temporary file and then read the number from that file before removing the file again. This works, but it leaves me with the nagging feeling that it is probably not the most efficient way of doing it. Is there a better way? How have others solved this problem?

Many thanks in advance,

Thomas

#include "Riostream.h"
ifstream in;
Int_t sec; 
gSystem->Exec("date | awk '{print $4}' | awk '{print $3}' FS=':' >tmpfile"); 
in.open("tmpfile"); 
in>>sec; 
in.close();
gSystem->Exec("rm -f tmpfile");

This sequence gives me the number of seconds stored in the Int_t sec.

Hi,

you could probably use gSystem->OpenPipe().

Cheers, Axel.

Thank you for the suggestion. I was not aware of that method. It indeed saves me some real time. I have replaced the above code with this:

Int_t sec = 0; 
char str[3];
FILE *f=gSystem->OpenPipe("date | awk '{print $4}' | awk '{print $3}' FS=':'","r"); 
fgets (str, 3, f);
fclose(f);
sec = atoi(str);

Running this and the first version (without the rm) 10000 times, I measure the following times:
gSystem->OpenPipe: Real time 0:01:54, CP time 15.340
gSystem->Exec() with tmp file: Real time 0:02:35, CP time 15.450
A noticeable, but not enormous speed up.

Thomas

Hi there,
It may be faster but it is still “heavy”.
Could it be possible just to get the output in a TString ?

[code]TString sec = gSystem->GetPipeOutput(“date | awk ‘{print $4}’”) ;[\code]
a bit like in perl :

That would be really nice !
Cheers, Z

Hi,
I’m sorry to insist but is there any reason not to implement such a feature?
Thanks, Z

Hi Z.,

this has now been implemented and is available in the trunk of today:

TString TSystem::GetFromPipe(const char *command);

Indeed quite convenient. :wink:

Cheers, Fons.

Thanks Fons :smiley: