Home | News | Documentation | Download

Output to log file AND terminal

I’m sure it has been asked before but I can’t find the topic.

Is it possible to direct the stdout both to a log file, and to the terminal ?

These methods only write the output into mylog.txt

root [0] .> mylog.txt
.x mymacro.C

(or inside the macro itself)

… lines of code …

ROOT Version: 6.24/00
Platform: Centos 7


You can use tee:

Thank you for the answer. In my tests tee worked to save the whole root session, i.e.

root -l | tee mylog.txt
.x mymacro.C

However, the tab autocompletion or the up arrow to find previous commands stops working.

Do you know if there is similar tool within root?

Why I want this? I’m using TMVA and want to store the ranking of the variables in a file, which is only possible by redirecting the output. But I also want to see the progress of the training in the terminal.

Ideally, gSystem->RedirectOutput(“mylog.txt”); could include an option to redirect the output to both the file and the terminal. I don’t know how difficult to implement would that be though… But it seems handy to save parts of the output without loosing the the interactivity.

You can always do (from the shell, not the ROOT prompt):

$ root -l -b -q mymacro.C | tee outputfile.log

or in any case, you can definitely start your application from the terminal and use tee or similar terminal tools. You don’t have to run your code from inside the ROOT prompt, it’s just a convenience (sometimes :grinning_face_with_smiling_eyes: ).

Ok, thank you @eguiraud for the suggestion. It’s a bit inconvenient to specify the target log file for each run (especially when all the output of each run goes to a different directory). Thus in my case it would be better to save the output from within the macro. But this definitely works for my initial question.

For anybody interested in the meaning of the options “root -l -b -q”, and how to pass arguments to the script, see this chapter of the User’s Guide

Hi @jruizvid,

If you pipe the output to tee, the standard output file descriptor is no longer a TTY device. POSIX TTY (or pseudo-terminal) semantics differ from those of a pipe. For low-level details (if you find those interesting), please refer to the following manual pages:

$ man 4 tty
$ man pts

That said, the most straightforward way to attain the desired behavior is via Tcl expect. This program allows you to automate input/output to an external program. The package is available in most GNU/Linux distributions, e.g., to install it on Ubuntu:

$ sudo apt-get install expect

For your particular use case, I would do the following (assuming that root executable can be reached via PATH):

$ expect
log_file root_output.log
spawn root -l
root [0] // type your code here; <Tab>, etc. can be used normally.
root [1] .q
expect1.3> exit

All the output will be logged to root_output.log -actually, it will include TTY control sequences, e.g., color changes. Therefore, the best way to visualize this is via $ less -R root_output.log.


Thank you @jalopezg. This is a very nice solution to record an interactive root session, having the common shortcuts like tab, up arrow, etc. (which tee cannot do). I will keep it in mind.

However the actual desired behavior was to direct the output both to the terminal, and to a file specified from within the macro, so that it could be saved in some specific directory with the rest of the output. I understand that it is not possible currently.

Hi @jruizvid,

AFAIK, gSystem->RedirectOutput() makes the stdout/stderr file descriptors point to the user-specified file; therefore, output is no longer seen in the TTY. As a workaround, I could suggest two alternatives:

  1. Use expect and log output to a temporary file; you can rename/link/copy under a different pathname from within the macro.

  2. Use gSystem->RedirectOutput() to redirect output to an arbitrary file. Spawn (either from your macro or by some other means) a tail -f process that outputs to the TTY.

I’d prefer the first option, as it is cleaner and you can still use <Tab>, etc. in the ROOT prompt.