Я думаю, что вы спрашиваете, как передать команды на стандартный ввод candc
, как если бы вы запустили его в командной строке и набрали команды на своем интерфейсе.
Если вы можете пройти все команды сразу, как одна большая строка (предположительно присоединился к новой строкой), вы можете сделать это с параметром input
, как показано в примерах в check_output
документы:
cmd="bin/candc --models models"
commands="""first candc command
second candc command
third candc command
"""
subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'),
input=commands)
Если это Python 3.x, вы также должны использовать закодированные байты для commands
или добавить universal_newlines=True
, чтобы сделать check_output
сделать это за вас. Если ваши команды являются чистыми ASCII, первое проще; просто измените эту строку на commands = b"""…
.
Если это версия с достаточно старыми версиями (я думаю, это означает 2.6/3.2, но я не уверен, проверьте документы, связанные выше), параметр input
еще не существует. В этом случае, у вас есть три варианта:
- Install
subprocess32
от PyPI, которого Backports новой версии библиотеки для более старых версий Python.
- Посмотрите, как current source обрабатывает аргумент
input
и выполняет то же самое самостоятельно.
Popen.communicate
принял аргумент input
до check_output
, поэтому вы можете просто создать Popen
и позвонить по нему communicate
.
Последний, по сути, просто более простой вариант второго ... но это намного проще. На самом деле, это всего лишь два лайнера, если вам не нужны все дополнительные сложности обработки тайм-аутов и делать что-то с выходом и так далее:
p = subprocess.Popen('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'), stdin=PIPE)
p.communicate(commands)
Если вам нужно отправить команды в интерактивном режиме (дождитесь ответа до отправки следующего), то check_output
не может этого сделать. Это всего лишь удобная обертка вокруг объекта Popen
. Вместо этого вы захотите создать объект Popen
явно, затем выполните p.stdin.write
и p.stdout.read
, чтобы установить связь с ним.
Например, быстрый & грязная версия может быть:
p = subprocess.Popen('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'),
stdin=PIPE, stdout=PIPE)
for command in commands.splitlines():
p.stdout.readline() # read and ignore a prompt
p.stdin.write(command + '\n')
rc = p.wait()
if rc: raise SomeException() # this is the check in check_output
Но этот код может блокировать, если, скажем, запрос является еще более чем одна линия, или это не гарантировано, чтобы поместиться в одном буфер, или ...
В целом, это может быть очень сложно. (Сам Python не понял этого в функции communicate
до 3.2 или 3.3 ...) Особенно, если вы не понимаете, что говорят документы с блокировкой выходного канала. Поэтому, если это действительно то, что вам нужно, вы можете захотеть использовать стороннюю библиотеку, созданную для запуска интерактивных программ командной строки, например pexpect
, вместо того, чтобы делать это самостоятельно.
Почему вы подразумеваете под «вставить больше команд»? Вы хотите передать команды на стандартный ввод 'candc'? – abarnert
есть. когда этот подпроцесс запущен, он находится в среде candc и ожидает получения предложения. поэтому я просто хочу передать любое предложение. – mid
Существует около 30 разных вещей под названием 'candc', поэтому я не знаю, какой из них вы используете; это поможет поставить ссылку на вопрос. Но важная часть: имеет ли она интерактивное приглашение, которое вы хотите использовать в интерактивном режиме (например, вы не знаете, что отправить или, по крайней мере, когда отправить следующее, до получения ответа/подсказки) ? – abarnert