3

I have a fortran program (which I cannot modify) that requires several inputs from the user (in the command line) when it is run. The program takes quite a while to run, and I would like to retain use of the terminal by running it in the background; however, this is not possible due to its interactive nature.

Is there a way, using a bash script or some other method, that I can pass arguments to the program without directly interacting with it via the command line?

I'm not sure if this is possible; I tried searching for it but came up empty, though I'm not exactly sure what to search for.

Thank you!

ps. I am working on a unix system where I cannot install things not already present.

3
  • Depending on how input is read, piping into stdin might work. Commented May 19, 2015 at 1:13
  • You can't open up another terminal session to do your non-Fortran work? Commented May 19, 2015 at 1:27
  • I can open another terminal... but there is A LOT of Fortran work to be done. Commented May 19, 2015 at 4:17

2 Answers 2

6

You can pipe it in:

$ cat delme.f90 program delme read(*, *) i, j, k write(*, *) i, j, k end program delme $ echo "1 2 3" | ./delme 1 2 3 $ echo "45 46 47" > delme.input $ ./delme < delme.input 45 46 47 $ ./delme << EOF > 3 2 1 > EOF 3 2 1 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! This is exactly what I needed, and I had no idea that it was even possible, let alone so simple. I particularly like the second solution.
Is this answer specific to fortran 90? Or perhaps a specific fortran compiler (gfortran vs f77). I have the same question, but am working with some legacy fortran 77 code.
This is independent of the compiler, it works with the shell. So it would depend on your operating system. Any Linux or MacOS should be fine, but I don't know about Windows.
You can also use here-strings: ./program <<< 42. If program reads input more than once, you can insert newlines using ANSI C strings ./program <<< $'42\n19'.
0

Try the expect/autoexpect Linux commands. Arcane, but extremely useful.

I'm still working out how to use expect myself, but here's an example of an interactive bash script that I got to work with expect (expect apparently works with any interactive command-line program/script, so this could also be done with a Fortran program).

This is the bash script, named "my_interactive_script.sh":

#!/bin/bash lat_lon_str=$1 echo lat_lon_str is $lat_lon_str echo "Howdy" echo " Hello, who is this?" read name echo "here is another question" echo "What's your favorite color?" read colour echo "How many cats do you have?" read n echo "${name}'s favourite colour is $colour; he has $n cats; he lives at lat/lon $lat_lon_str" 

If I call this script with ./my_interactive_script.sh "49.0, -123" and provide the interactive responses when prompted, I get this output:

lat_lon_str is 49.0, -123 Howdy Hello, who is this? Bob here is another question What's your favorite color? red How many cats do you have? 47 Bob's favourite colour is red; he has 47 cats; he lives at lat/lon 49.0, -123 

To run this script non-interactively, I create an expect script named "invoke_script.exp":

#!/usr/bin/expect set lat_lon_str [lindex $argv 0] spawn ./my_interactive_script.sh $lat_lon_str expect -re ".*is this.*$" send -- "Jim\r" expect -re "ite co.*$" send -- "cyan\r" expect -re "you have?" send -- "zero\r" expect eof 

If I call the expect script with expect invoke_script.exp "49.5, -123.0" , then I get this output:

spawn ./my_interactive_script.sh 49.5, -123.0 lat_lon_str is 49.5, -123.0 Howdy Hello, who is this? Jim here is another question What's your favorite color? cyan How many cats do you have? zero Jim's favourite colour is cyan; he has zero cats; he lives at lat/lon 49.5, -123.0 

The expect script has answered the interactive questions with the hard-coded stock answers "Jim", "cyan", and "zero", with no need for user interaction.

You'll notice I used the "-re" option with expect to allow the use of regular expressions. I found this to be critical to making expect work with this example. If I didn't use regular expressions, the script would hang. I found that expect was trying to match some weird concatenation of the current prompt string and parts of the previous prompt strings (call expect with the -d option to see verbose output for debugging purposes). I don't understand this, but it may have something to do with the "buffers" the man page talks about. Presumably there's a correct way to clear the buffers as you go, but this regexp solution was an easy workaround.

2 Comments

Can you provide an example of how to do this? That would make this answer much more useful.
@Chris, I added an example, as requested.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.