Search code examples
command-linefortranstdoutwait

How to run an executable and then read the output file in Fortran?


I want to write a Fortran program that can run an executable called external_program.x and then wait until it produces an output file called output.dat, which contains 10 lines of 3D coordinates. The output file looks like this:

0.8 1.8 2.8
1.2 1.3 1.4
2.2 2.3 2.4
5.4 5.3 5.1
2.5 2.6 2.7
1.0 1.1 1.2
0.8 0.2 0.1
4.4 4.3 4.2
2.5 2.1 1.2
3.5 3.6 3.9

I wrote the following Fortran code, but it doesn't work, because the main script will not wait for the job to finish, but go directly to read the output file which is non-existent yet. I don't want to implement sleep because the output file will be produced super fast (within 0.1 s), and sleep will make it very slow. Tbh I don't even know how to implement sleep in fortran. Is there a way to get the stdout as soon as the job finishes? I tried wait=.true. in execute_command_line, but it doesn't work.

real dimension(10) :: x, y, z
real, dimension(10,3) :: coords
integer :: i

! run executable
call execute_command_line ("./external_program.x", wait=.true.)

! read output file
open (unit=99, file="output.dat", status="old")
do i=1,10
  read(99,*) x(i), y(i), z(i)
  coords(i,1) = x(i)
  coords(i,2) = y(i)
  coords(i,3) = z(i)
end do
close(99)

do i=1,10
  print "(F20.8,F20.8,F20.8)", coords(i,1), coords(i,2), coords(i,3)
end do

Solution

  • On the top of my head I can think of the following ways to achieve your goal.

    Method 1 (my preferred way): The call of external programs is usually done by scripting languages and I would use python for that. There you can easily check if the command has finished and the output file exists/is of correct size. If true, then you can call your fortran program from the python script.

    Method 2: The option wait=.true. will make your fortran program wait until the other program has finished. But there is a slight catch: I guess that the output might still be in the process of being written which is why you are getting errors. Maybe you want to use a workaround where you either wait a specific time (the sleep command might be of help gfortran-doc) or/and you could check if the file exists and has correct size.

    • check if file exists: inquire(file="myfile.csv", exist=file_exists)
    • check file's size: inquire(file="myfile.csv", size=file_size)