从外部程序交互式编写/读取

时间:2015-06-09 19:59:03

标签: python subprocess

背景故事:我对Python很陌生,但在Perl方面经验丰富。我试图在sysadmin-activities区域实现脚本组合的多样化。

我试图从我的python脚本中动态地与外部进程通信。

我想做的是:

  • 调用可执行文件(让我们称之为" cli")
  • 给cli写一行
  • 内部阅读回复
  • 逐个迭代响应,并将另一行写入CLI
  • 将cli的响应打印回控制台

我希望这会产生的是:

(spawn process) /usr/local/bin/cli
-> show listofobjects
<- (read back list of objects internally)
-> (one by one, write a line to the cli for each of the list of objects)
-> get objectname modifiedtime
<- (print response from above command)

这是我到目前为止的代码:

import shlex, subprocess, re

clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password"
cliargs = shlex.split(clicmd)
cliproc = subprocess.Popen(cliargs,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                      )

tmpclicmd = "LIST objects OUTPUT csv NAME"
cliret = cliproc.communicate(input=tmpclicmd)[0]
regex = re.compile('^\".*')

for line in cliret.split('\n'):
    if regex.match(line):
        procline = line.replace('"','')
        if 'NAME' not in procline:
            clideets = subprocess.Popen(cliargs,
                                        stdin=subprocess.PIPE,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE,
                                       )
            clideetscmd = 'modify objects ' + procline
            clideets.communicate(input=clideetscmd)
            clideetscmd = 'list objectdetails'
            clideetsresp = clideets.communicate(input=clideetscmd)[0]

            print clideetsresp;

我可能会以完全错误的方式解决这个问题。我是否必须为每一步产生一个新的Popen?我怎么能做得更好? (另一个模块等)。在一天结束时,我无法接近我,这是Popen在每一步之后所做的事情。

提前致谢!

1 个答案:

答案 0 :(得分:3)

  1. 没有必要为每次互动启动新流程(使用Popen)。但是,当您使用communicate向进程发送数据时,您会这样做,因为正如文档所述:

      

    与流程交互:将数据发送到stdin。从stdout和。读取数据   stderr,直到达到文件结尾。 等待进程终止。

    相反,只需写入cliproc.stdin并从cliproc.stdout读取:

    cliproc.stdin.write("LIST objects OUTPUT csv NAME")
    cliret = cliproc.stdout.readline()
    

    这个过程保持这种方式。

  2. 我不知道你在这里使用shlex模块的原因:

    clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password"
    cliargs = shlex.split(clicmd)
    

    内置的str.split方法可以正常使用:

    clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password"
    cliargs = clicmd.split()
    

    或者您可以自己编写结果列表:

    cliargs = ["/usr/local/bin/cli", "-s", "10.1.213.226",
               "-n", "Administrator", "-p", "password"]
    
  3. 这里你不需要分号:

    print clideetsresp;