-1

I'm trying to run a few commands in a Athena Vortex Lattice using Python subprocess, but it keeps throwing errors:

C:\Users\Myself\AppData\Local\Programs\Python\Python35\python.exe C:/Users/Myself/Documents/aerodynamics/analyze_cases.py
Root:  C:\Users\Myself\Documents\aerodynamics
At line 145 of file ../src/userio.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
Traceback (most recent call last):
  File "C:/Users/Myself/Documents/aerodynamics/analyze_cases.py", line 31, in <module>
    process.communicate(b'\n')
  File "C:\Users\Myself\AppData\Local\Programs\Python\Python35\lib\subprocess.py", line 1043, in communicate
Loaded
    raise ValueError("Cannot send input after starting communication")
ValueError: Cannot send input after starting communication

Process finished with exit code 1

This is the code used:

import time
import subprocess
import os

root = os.getcwd()
print("Root: ", root)

# Start AVL Program
process = subprocess.Popen([root+r"/avl.exe "], shell = True, stdin=subprocess.PIPE, bufsize=1,  stdout=subprocess.PIPE)

time.sleep(2)

# Start program with LOAD and filename:    
process.communicate(input=b"LOAD "+root.encode()+b"\input_cases\sample.avl \n")

time.sleep(2)
print("Loaded")

process.communicate(b'\n')
time.sleep(5)

print("Leaving")
# process.communicate(b'\n')
process.communicate(b'\n')
time.sleep(0.5)
process.communicate(b'QUIT')

process.kill()

My thoughts: It appears at the first communicate statement already (before Loaded) and crashes when it tries to fire off the second command to a now nonexistent process.

My Theory: Judging from the log there may be something going on with unit = 5, file = 'stdin' (why is file equal to stdin?) but I don't have a clue how to solve that.

There are a few similar questions around here, and I've tried the following hacks:

  • shell true/false
  • encode() and bitstring stuff
  • subprocess communicate instead of stdin.write
  • Same issue appears with wine on Mac. Program runs nominally with identical commands directly command line outside Python.
MaxQ
  • 595
  • 1
  • 8
  • 25
  • Try `print`ing the stdout of the first communicate. this might give you a clue. – Andrey Sobolev Oct 09 '15 at 10:18
  • avoid cargo cult programming. (1) [Understand when you should or should not use `shell=True`](http://stackoverflow.com/q/2400878/4279) (2) know [what `.communicate()` does](https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate) (it should be obvious that it is pointless to call `.communicate()` more than once). Unrelated: use `universal_newlines=True` to enable the text mode (to avoid sprinkling the code with bytes literals `b''`). – jfs Oct 09 '15 at 10:33

1 Answers1

1

Here's a code example where some issues in your code are fixed. You should consider whether you could get rid of time.sleep() too:

#!/usr/bin/env python3
import os
import time
from subprocess import Popen, PIPE, DEVNULL

# start AVL Program
with Popen(os.path.abspath("avl.exe"), stdin=PIPE, stdout=DEVNULL, bufsize=1,
           universal_newlines=True) as process:
    time.sleep(2)
    # start program with LOAD and filename:    
    print("LOAD " + os.path.abspath(r"input_cases\sample.avl"), file=process.stdin)
    time.sleep(2)
    print(file=process.stdin) # send newline
    time.sleep(5)
    print(file=process.stdin) # send newline
    time.sleep(0.5)
    print("QUIT", file=process.stdin)
jfs
  • 399,953
  • 195
  • 994
  • 1,670