Writing to screen and file at the same time/line

Hi guys, I notice there is no one discuss this.

I am now doing an analysis that takes hours to finish. It would be convinient to debug something if I print each step of my calculation (for example, opening this, or doing that) to the screen. However, when the actual analysis is done, it is helpful to write it in to a log file, together with the clock time. Therefore, we kinda need both writing (to screen and to log file).

Yep, no one discuss how to write something to screen and file together at the same time/line. Is there a trick here or we should separate it into two lines? thank you masters~

1 Like

The discussion at Allowing an INTEGER array as a LUN on WRITE() statements · Issue #192 · j3-fortran/fortran_proposals · GitHub is pertinent. If you are using GNU/Linux or Unix, see the tee(1) command (“man tee” shows the documentation). You can do something like “myprogram |tee log.txt” and output will go to both the screen and stdout; for example.
Not sure if there is something similiar on MSWindows; but in the collection at

there is also the Fortran example program

https://urbanjost.github.io/general-purpose-fortran/docs/ttee.1.html

GitHub - urbanjost/M_msg: convert all common variables to a string in Fortran using unlimited polymorphic variables

(which is also included in the GPF collection) has a procedure called “wrt” that also addresses this.

Another way to use tee(1) is to just write to the log file and background the command (or use another window) and use “tee -f log.txt”. If your program writes to stdout currently, you would do something like

myprogram > log.txt &
tail -f log.txt

the advantage of that is you can kill the tail(1) command but the program will keep running.

6 Likes

One question. Yes, I am using GNU Fortran compiler now, but it maybe changed to intel Fortran compiler in the future. Do you think it is compilable with the intel Fortran?

Thanks for your help~

1 Like

All the code mentioned works with ifort and gfortran

Strange, my gfortran does not allow array as IO statement. It says
Error - External IO UNIT cannot be an array

When I’m in your situation I use an integer array called u of unit numbers in this way:

do i = 1,size(u)
   write(u(i),format) stuff
end do

where i is an integer, and format and stuff depend on what you’re writing. That works with both gfortran and ifort because u(i) is a scalar element of an array, not the whole array that gfortran quite rightly objected to. Being plain Fortran it doesn’t need tee, which may work differently in different operating sytems or not at all in some.

The tee utility mentioned above is standard POSIX. This is pretty much exactly what it is designed to do. It works with programs written in any language, including of course fortran. It reads standard input and writes two copies, one to standard output and the other to a file. The usual way to use it is

program | tee output.log

The standard output that would have appeared on your screen (for example) will still appear on your screen, but it will also appear in output.log. If you want more than one output file, then you can just string them together on the command line

program | tee output.log | tee other.log

Another way to do this is with the tail command.

program > output.log &
tail -f output.log

Here the program is running in the background, so it runs while you do other things. One of those things might be to look at the output.log file as it is being appended. However, in this case, you may find that the output is buffered to the file, so the tail command will appear to stall for a while and then it will print a few lines of output, and then it will stall for a while again. However, in this case, the output.log file does not need to be standard output, it could be a normal file opened in fortran in the usual way, so this solution is somewhat more general. You can do somethiing similar with less output.log, and that gives you the ability to scroll both backwards and forwards in the file while it is being written, do text searches, and so on within the file.

3 Likes

Meant to show tail(1) in my example, corrected it (I said “tee -f” instead of “tail -f”). Note that at least some tee(1) commands allow multiple output file names, so “program|tee A B” writes to both A and B.

1 Like

I think you might be trying a lun array with a WRITE statement? That discussion I referenced is a proposal to add that to WRITE(); it does not current support it. Some of the discussion shows examples of how to simulate that, and what the current state is; which is why I referenced it.

Thank you for all your help~