python脚本如何处理第二个shell并在该shell中输入命令

时间:2018-04-05 15:05:43

标签: python shell

我想使用python实现以下过程:

[zz@bts01 ~]$ cd /opt/cdma-msc/
[zz@bts01 cdma-msc]$ ./sccli
SoftCore for CDMA CLI (c) Quortus 2010
RAN> show system
System Configuration
  Software version:      V1.31
  System name:           RAN
  System location:
  Shutdown code:
  Emergency call dest:
  Current date/time:     Tue Feb 27 14:27:41 2018
  System uptime:         20h 33m
  Auto-provisioning:     Enabled
RAN> exit
Bye.
[zz@bts01 cdma-msc]$

请看上面,我想使用python来调用这个/ opt / cdma-msc / rancli进程,这将打开一个辅助shell,我想捕获命令的输出" show license"在那个壳里。我怎么能在python中实现这一点? 我尝试使用子进程Popen,并且能够调用shell,但无法输入任何内容。有人有想过吗?

ran = subprocess.Popen(['/opt/cdma-msc/sccli'], shell = True, stdout = subprocess.PIPE)
hnb = subprocess.Popen(['show system'],stdin=ran.stdout )

上面是我试过的python模块/命令,显然第二行没有从第一行获取输出,casue它正在调用另一个shell。

1 个答案:

答案 0 :(得分:1)

您希望该命令是您创建的子流程的输入,而不是新子流程的名称。

如果你有足够新的Python,请尝试

output = subprocess.run(['/opt/cdma-msc/sccli'],
    stdout = subprocess.PIPE,
    input='show system',
    check=True, universal_newlines=True).stdout

run返回的结果是一个对象,它封装了子进程的结果代码和状态以及它的输出。其stdout成员包含标准输出中生成的文本。

不幸的是,run仅在Python 3.5中引入,但它足够改进,您可能不希望不支持旧版本的Python。如果您必须支持旧版本,则等效代码相当笨重:

p = subprocess.Popen(['/opt/cdma-msc/sccli'],
    stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = p.communicate('show system')

在这里,stdout只是一个带有输出的字符串。

您通常应该避免使用原始Popen(),除非更高级别的包装绝对不能达到您想要的效果。当没有通配符,管道,重定义甚至参数解析时(你已经将命令行打破为字符串列表),显然也不需要shell=True