来自外部程序的交互式 writing/reading

Interactively writing/reading from an external program

背景故事:我是 Python 的新手,但对 Perl 相当有经验。我正在努力使我在系统管理员活动领域的脚本组合多样化。

我正在尝试通过我的 python 脚本与外部进程进行动态通信。

我想做的是:

我希望这会产生的结果是:

(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?我怎样才能做得更好? (另一个模块等)。在一天结束的时候,我无法让 cli 关闭,而 Popen 似乎在每一步之后都会这样做。

提前致谢!

  1. 不必为每次交互都启动一个新进程(使用 Popen)。但是,当您使用 communicate 将数据发送到进程时,您会这样做,因为正如文档所述:

    Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.

    相反,只需写入 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;