简体   繁体   中英

Python: Using subprocess to give input to another program

I am trying to use Python to automate running another program repeatedly. Right now I am typing the following into the command line, one at a time (the numbers come from the file "Avals"):

advisersProgram
input1
0.01
input1
0.015
exit

When I try to automate it, I can launch advisersProgram but I can't send it the inputs.

This is what I have tried:

import os
import glob
import subprocess

files = sorted(glob.glob("*"))
for f in files:
    os.chdir(f)
    As = [float(line.strip()) for line in open("Avals")]
    subprocess.call('advisersProgram')
    for A in As:
        subprocess.call('input1')
        subprocess.call(A)
    subprocess.call('exit')
    os.chdir("..")

I have also tried

for f in files:
    As = [float(line.strip()) for line in open("Avals")]
    subprocess.call(['advisersProgram','input1',A[0],'input1,A[1]','exit'])

and

for f in files:
    As = [float(line.strip()) for line in open("Avals")]
    subprocess.Popen('advisersProgram',stdin=['input1','0.01','input1','0.015','exit'])

Other info: I looked into Pexpect (I am not sure if this would be useful but it was suggested in one of the stack exchange answers I read), but I do not have that installed and do not have the authority to install it.

I don't need to capture any output; advisersProgram generates contour plots which are saved in the directory.

Consider passing a list of command line parameters in the args argument of subprocess.Popen , not in the stdin argument. Below shows how stdin (standard input) can be used to output to Python console the output and/or error of child process.

import glob, os, subprocess

# PATH OF PY SCRIPT (CHANGE IF CHILD PROCESS IS NOT IN SAME DIRECTORY)
curdir = os.path.dirname(os.path.abspath(__file__))   

files = sorted(glob.glob("*"))
for f in files:                 # NOTE: f IS NEVER USED BELOW, SHOULD IT BE IN OPEN()?
    As = [float(line.strip()) for line in open("Avals")]
    for A in As:
        p = subprocess.Popen(['advisersProgram', 'input1', A], cwd=curdir,
                   stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output,error = p.communicate()  

        if p.returncode == 0:            
           print('OUTPUT:\n {0}'.format(output.decode("utf-8")))            
        else:                
           print('ERROR:\n {0}'.format(error.decode("utf-8")))  

Of course if you do not need any output, remove such lines but you may want to track which child processes worked or not.

Ah, I was wrong - it wasn't communicate() . You just want to setup stdin as a subprocess.PIPE

import sys
import subprocess


def call_myself():
    print('Calling myself...')
    p = subprocess.Popen([sys.executable, __file__], stdin=subprocess.PIPE)
    for command in ['input1', '0.01', 'input1', '0.015', 'exit']:
        p.stdin.write((command+'\n').encode())


def other_program():
    command = None
    while command != 'exit':
        command = input()
        print(command)
    print('Done')


if __name__ == '__main__':
    try:
        if sys.argv[1] == 'caller':
            call_myself()
    except IndexError:
        other_program()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM