在正在运行的程序中运行python脚本

时间:2016-12-07 21:08:19

标签: python bash shell sh executable

我正在运行一个python脚本,它启动一个名为./abc的可执行文件。这个可执行文件进入程序内部并等待一个命令:

$./abc
abc >                      \\waits for a command here.

我想做的是输入几个命令,如:

$./abc
abc > read_blif alu.blif
abc > resyn2

到目前为止我所拥有的内容如下:

import os
from array import *

os.system('./abc')
for file in os.listdir("ccts/"):
    print 'read_blif ' + file + '\n'
    print 'resyn2\n'
    print 'print_stats\n'
    print 'if -K 6\n'
    print 'print_stats\n'
    print 'write_blif ' + file.split('.')[0] + 'mapped.blif\n'

然而,这将执行以下操作:

abc >                 \\stays idle and waits until I ^C and then it prints
read ...blif
resyn2
...

它只打印到终端。如何在程序中执行此操作并等到它看到下一个abc>运行下一个命令。 感谢

4 个答案:

答案 0 :(得分:1)

我使用subprocess做了类似的事情。

import subprocess

cmd = './command_to_execute'
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
result = pro.stdout.read()

这将执行cmd指定的命令,然后将结果读入result。在结果分配后执行任何操作之前,它将等待打印到控制台的结果。我相信这可能是你想要的,虽然你的描述有点模糊。

答案 1 :(得分:1)

您可能正在寻找pexpect模块。以下是pexpect文档的基本示例

# This connects to the openbsd ftp site and
# downloads the recursive directory listing.
import pexpect
child = pexpect.spawn('ftp ftp.openbsd.org')
child.expect('Name .*: ')
child.sendline('anonymous')
child.expect('Password:')
child.sendline('noah@example.com')
child.expect('ftp> ')
child.sendline('lcd /tmp')

如果您的操作系统与pexpect兼容,我认为它与abc>的工作方式相同。

答案 2 :(得分:0)

如果要将命令传递到可执行文件的输入中,最简单的方法是使用subprocess模块。您可以输入可执行文件的stdin并使用Popen.communicate获取其输出。

import subprocess

for f in os.listdir('ccts/'):
    p = subprocess.Popen('./abc', stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate('read_blif ' + f + '\n'
                                   'resyn2\n'
                                   'print_stats\n'
                                   'if -K 6\n'
                                   'print_stats\n'
                                   'write_blif ' + f.split('.')[0] + 'mapped.blif\n')
    # stdout will be what the program outputs and stderr will be any errors it outputs.

但是,每次都会关闭子进程的stdin,但这是在没有死锁的情况下进行可靠通信的唯一方法。根据{{​​3}},您应该使用pexpect进行"交互式会话"程序。这可以通过多个子进程来避免,假设您可以让不同的子进程运行该程序。

我假设您只需要stdout的{​​{1}},所以您可以这样做(例如,您可能想要处理错误):

print_stats

答案 3 :(得分:0)

您需要使用<div> <img id="image" width="100" src="https://placehold.it/100x100?text=✔"> <button onclick="copyElement('image');">Copy image</button> </div> <script> function copyElement(id) { var element = document.getElementById(id); var text = document.createElement("textarea"); document.oncopy = function(e) { e.clipboardData.setData("text/plain", text.value); console.log(e.clipboardData.getData("text/plain")); } fetch(element.src.replace(/^(http:|https:)/, location.protocol)) .then(function(response) { return response.blob() }) .then(function(blob) { var reader = new FileReader(); reader.onload = function() { document.body.appendChild(text); text.value = reader.result; text.select(); alert("Press CTRL+C to copy image to clipboard"); } reader.readAsDataURL(blob) }) } </script>库生成一个新流程,并为Sub PopulateTable() Dim ws As Worksheet Dim vSourceData As Variant Dim aResults() As String Dim bBackwards As Boolean, bFull As Boolean Dim lRowIndex As Long, lColIndex As Long Dim i As Long, j As Long Set ws = ActiveWorkbook.ActiveSheet With ws.Range("A2:B" & ws.Cells(ws.Rows.Count, "A").End(xlUp)) If .Row < 2 Then Exit Sub 'No data vSourceData = .Value End With ReDim aResults(1 To 20, 1 To 24) lRowIndex = 1 lColIndex = 1 bBackwards = False bFull = False For i = 1 To UBound(vSourceData, 1) For j = 1 To vSourceData(i, 1) aResults(lRowIndex, lColIndex) = vSourceData(i, 2) If bBackwards Then lColIndex = lColIndex - 1 Else lColIndex = lColIndex + 1 If lColIndex = 0 Then lRowIndex = lRowIndex + 1 lColIndex = 1 bBackwards = Not bBackwards ElseIf lColIndex = UBound(aResults, 2) + 1 Then lRowIndex = lRowIndex + 1 lColIndex = UBound(aResults, 2) bBackwards = Not bBackwards End If If lRowIndex > UBound(aResults, 1) Then bFull = True 'No more room in results array If bFull Then Exit For Next j If bFull Then Exit For Next i With ws.Range("E2").Resize(UBound(aResults, 1), UBound(aResults, 2)) .ClearContents 'Clear previous results (if any) .Value = aResults 'Output results End With End Sub 创建一个管道,为subprocess创建一个管道。使用此管道(在python中表示为文件),您可以与您的流程进行通信 这是一个例子:

stdin

您可以使用stdout但我认为您需要为输入的每个命令获取输出。类似的东西:

 import subprocess

cmd = './full/path/to/your/abc/executable'
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, 
                       stdin=subprocess.PIPE)

pro.stdin.write("read_blif alu.blif \n")
pro.stdout.read(3)

通过这种方式,我认为pro.communicate方法更有用。

使用python中的abc > command1 ouput1 abc > command2 output2 -part1 output2 -part2 output2 -part3 函数查找有关PIPE对象的更多信息以及可用的方法和属性dir。不要忘记内置的pro,它会显示文档字符串dir(proc)help

当你运行help(pro)时,你会犯一个错误,这会让你在后台运行程序而你无法控制它。也许你想研究一下输入/输出流。 可以进行更多阅读here