У меня есть исполняемый файл, называемый tsfoil2.exe, и я хочу использовать этот.exe из моей среды python. Я запускаю Python 2.7.3 с Spyder 2.1.11 в Windows 7.
Для работы с.exe требуется некоторый ввод, жесткий диск по умолчанию ("I: \"), имя для выходного файла ("test") и имя для входного файла ("SC20610.inp"),
Один из моих коллег посоветовал мне использовать os.system и снабдить его временным входным файлом, который содержит все аргументы.
f = open('temp', 'w')
f.write('I:\ \n')
f.write('test \n')
f.write('SC20610.inp\n')
f.close()
Затем я передаю этот файл аргументам в.exe следующим образом:
os.system("tsfoil2.exe < temp")
Все это работает, но для завершения программы требуется "ВВОД". По какой-то причине.exe неоднократно запрашивает "Нажмите клавишу ENTER, чтобы выйти". Даже когда я нажимаю клавишу ввода в моей Spyder-консоли, программа не прерывается.
Есть ли способ дать ключ "ENTER" в качестве интерактивного входа в.exe? Я попытался использовать класс SendKeys, но по мере того, как программа не заканчивается, она не достигает строки кода, содержащей команду SendKeys. Я также попытался включить его в файл аргументов, но это тоже не сработает.
Кроме того, я также выяснил, что было бы полезно переключиться на команду subprocesses, так как это может дать мне больше команд для выполнения, но я не смог запустить исполняемый файл с входными файлами.
Можно ли предоставить необходимое "ENTER" с помощью os.system или переключиться на подпроцесс, и если да, то как я могу построить метод, подобный os.system("tsfoil2.exe <temp"), я используя сейчас.
Я пробовал это:
import subprocess as sub
f = open('temp', 'w')
f.write('I:\ \n')
f.write('test \n')
f.write('SC20610.inp\n')
f.close()
proc=sub.Popen(["tsfoil2.exe","temp"], shell=True)
и это
import subprocess as sub
p=sub.Popen('tsfoil2.exe')
p.communicate(input='I:' )
Но программа не отвечает на приведенные аргументы.
MWE:
import os
f = open('temp', 'w')
f.write('I:\ \n')
f.write('test \n')
f.write('SC20610.inp\n')
f.close()
os.system("tsfoil2.exe < temp")
Обе программы можно найти через http://www.dept.aoe.vt.edu/~mason/Mason_f/tsfoil2.exe, входной файл можно найти по адресу http://www.dept.aoe.vt.edu/~mason/Mason_f/SC20610.inp.
Надеюсь, все ясно, и вы можете мне помочь.
'Press the ENTER key to exit'
означает, что программы ожидают новую строку.
Я не вижу пустой строки в конце temp
файла. Кроме того, возможно, вы имели в виду 'I:\\\n'
- вам нужно использовать '\\'
в строковом литерале Python, если вы хотите \
на выходе.
Вопрос в том, что tsfoil2.exe
рассматривает новую tsfoil2.exe
например, b'\r\n'
или просто b'\n'
и где он ожидает ее получения: от stdin (getchar()
) или непосредственно с консоли (getch()
),
Предполагая, что программа ожидает b'\r\n'
от stdin в Windows:
import os
from subprocess import CalledProcessError, Popen, PIPE
cmd = "tsfoil2.exe"
input_data = os.linesep.join(['I:\\', 'test', 'SC20610.inp', os.linesep])
p = Popen(cmd, stdin=PIPE, bufsize=0)
p.communicate(input_data.encode('ascii'))
if p.returncode != 0:
raise CalledProcessError(p.returncode, cmd)
os.linesep == "\r\n"
в Windows. "\n".join(["a", "b"]) == "a\nb"
.
Каждый процесс может иметь три стандартных потока: stdin, stdout, stderr. В Python они представлены как sys.stdin
, sys.stdout
, sys.stderr
. Вы можете читать входные данные из stdin и записывать в stdout, stderr, например, функция input
считывает из stdin и print
записи в stdout по умолчанию. stderr может использоваться для записи сообщений об ошибках.
stdin=PIPE
сообщает Popen
создать канал между родительским процессом, в котором он вызывается, и новым дочерним процессом ("tsfoil2.exe") и перенаправляет подпроцесс "stdin". p.communicate(data)
записывает данные в p.stdin
, закрывает его и ждет завершения дочернего процесса. p.returncode
содержит статус выхода дочернего процесса. Обычно ненулевой статус означает отказ.
Он эмулирует конвейер оболочки, фактически не создавая оболочку:
$ echo input data | tsfoil2.exe
Если вход ожидается с консоли, вы можете попробовать модуль SendKeys
или его чистую реализацию Python SendKeys-ctypes
:
from SendKeys import SendKeys
SendKeys(r"""
{LWIN}
{PAUSE .25}
r
C:\Path\To\tsfoil2.exe{ENTER}
{PAUSE 1}
I:\{ENTER}
{PAUSE 1}
test{ENTER}
{PAUSE 1}
SC20610.inp{ENTER}
{PAUSE 1}
{ENTER}
""")
Я его не тестировал.
SendKeys
чтобы избежать неправильной интерпретации обратной косой черты (примечание: r"""..."""
). Введите `\` вручную, если copy-paste пытается вставить похожий символ Unicode вместо обратной косой черты.