Python 写入stdin并正确打印结果

Python 写入stdin并正确打印结果,python,subprocess,stdin,Python,Subprocess,Stdin,我有一个命令/rancli-c-我在一个shell中输入,该shell包含以下文档: 从Linux shell运行该工具可以提供其他选项, 取决于为命令提供的选项。选项如下: 如下: -h显示有关该命令的帮助 -c不是以交互方式从用户获取键入的命令,而是从命名文件(即批处理模式)读取命令。 处理完所有命令后,CLI会话将自动结束 -c-如上所述,但从LinuxStdin读取命令。这允许命令通过管道传输到程序 我想把它转换成python。如果我使用第二个选项,一切正常,它从文件中读取命令并在屏幕上

我有一个命令
/rancli-c-
我在一个shell中输入,该shell包含以下文档:

从Linux shell运行该工具可以提供其他选项, 取决于为命令提供的选项。选项如下: 如下:

-h显示有关该命令的帮助

-c不是以交互方式从用户获取键入的命令,而是从命名文件(即批处理模式)读取命令。 处理完所有命令后,CLI会话将自动结束

-c-如上所述,但从LinuxStdin读取命令。这允许命令通过管道传输到程序

我想把它转换成python。如果我使用第二个选项,一切正常,它从文件中读取命令并在屏幕上显示结果。但是,我想使用第三个选项,它写入stdin。我本以为这行会运行一个命令
/rancli-c-commandHere
,但它没有。我需要做的是输入
/rancli-c-
,然后我可以在下一行手动写入stdin,比如在这里我使用命令
read hnb

[root@switch]# ./rancli -c -
read hnb
RAN> read hnb
               HNBId                           Location      RegUEs   ActUEs
  000295-0000038828@ipaccess.com                    n/c
  000295-0000070688@ipaccess.com                    n/c
当我在shell中输入这个时,我可以很好地打印出结果。但是,当我在python中执行此操作时,我无法将结果正确地打印回我。以下是我尝试过的:

    ran_opt_get_ap  = "read hnb\n"
    cmd_rancli = ["/jffs2/usbflash0/ran/rancli", "-c", "-"]
    proc = subprocess.Popen(cmd_rancli + [ran_opt_get_ap], stdout=subprocess.PIPE)    
    for line in iter(proc.stdout.readline, ''): 
        print line,
    proc.wait()
因此,当我传入这样的命令时,它显然不像在shell中那样工作,并且被忽略。现在有两个问题,我如何在这里将命令写入stdin,因为我必须手动键入以下命令
readhnb
?在我运行
rancli-c-
之后,我想在之后注入命令,我现在必须像这样键入命令:

read hnb                                                                        
RAN> read hnb                   
另一个问题是,我的代码没有打印出上面的全部结果,但当我键入下一个命令时,我会得到其余的结果和下一个结果的第一行,依此类推,在键入下一个命令后得到结果:

get ap                                                                          
               HNBId                           Location      RegUEs   ActUEs    
  000295-0000038828@ipaccess.com                    n/c                         
  000295-0000070688@ipaccess.com                    n/c                         
RAN> get ap 
更新:最新代码有效

cmd_rancli = ["/jffs2/usbflash0/ran/rancli", "-c", "-"]
ran_opt_get_ap = "read hnb"
proc = subprocess.Popen(cmd_rancli, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate(ran_opt_get_ap)[0] 
print output

要写入子流程的stdin,请将其设置为管道:

from subprocess import Popen, PIPE

p = Popen(cmd_rancli, stdin=PIPE, stdout=PIPE)
output = p.communicate(ran_opt_get_ap)[0]
ran\u opt\u get\u ap
写入子进程的stdin,读取所有输出,并等待子进程完成

第二个问题是由于缓冲(只有当您没有一次读取所有输出时才重要)。要修复缓冲,请执行以下操作:

  • 对于程序的输出,在打印内容后添加
    sys.stdout.flush()
  • 将一端管道的Popen的
    bufsize
    参数设置为零
  • 对于子流程,请使用或

要写入子流程的stdin,请将其设置为管道:

from subprocess import Popen, PIPE

p = Popen(cmd_rancli, stdin=PIPE, stdout=PIPE)
output = p.communicate(ran_opt_get_ap)[0]
ran\u opt\u get\u ap
写入子进程的stdin,读取所有输出,并等待子进程完成

第二个问题是由于缓冲(只有当您没有一次读取所有输出时才重要)。要修复缓冲,请执行以下操作:

  • 对于程序的输出,在打印内容后添加
    sys.stdout.flush()
  • 将一端管道的Popen的
    bufsize
    参数设置为零
  • 对于子流程,请使用或

谢谢,我会尝试一下,对subprocess.PIPE或PIPE这样做有什么区别吗?stdin=subprocess.PIPE等?尝试了您的第一个建议:对于iter中的行(proc.stdout.readline“”):ValueError:I/O操作关闭file@Paul:rancli是否在其标准中忽略EOF?(手动运行时,请尝试键入
Ctrl D
)。如果是这样,;如何退出
rancli
,是否需要键入特殊命令才能退出?@Paul:
.communicate()
关闭子进程stdin,因此
rancli
应接收EOF(因此应退出)。如果在bash中运行:
echo read hnb | rancli-c->output
,会发生什么情况?@Paul:运行确切的命令。在末尾添加
>输出
。支票:1<代码>rancli退出2<代码>输出文件包含预期的输出。感谢您尝试,对subprocess.PIPE或PIPE执行此操作有何区别?stdin=subprocess.PIPE等?尝试了您的第一个建议:对于iter中的行(proc.stdout.readline“”):ValueError:I/O操作关闭file@Paul:rancli是否在其标准中忽略EOF?(手动运行时,请尝试键入
Ctrl D
)。如果是这样,;如何退出
rancli
,是否需要键入特殊命令才能退出?@Paul:
.communicate()
关闭子进程stdin,因此
rancli
应接收EOF(因此应退出)。如果在bash中运行:
echo read hnb | rancli-c->output
,会发生什么情况?@Paul:运行确切的命令。在末尾添加
>输出
。支票:1<代码>rancli退出2
output
文件包含预期的输出。drop
[ran\u opt\u get\u ap]
Popen()
调用中,添加
stdin=PIPE
,如我的回答所示<如果您使用
.communicate()
,则code>bufsize=0是不必要的,但在这里它也不会有什么坏处。谢谢,我按照您所说的那样使用了管道,它起到了作用。只需删除\r\n.@J.F.Sebastian,我提供了最新的代码,非常感谢。删除
[ran\u opt\u get\u ap]
Popen()
调用中,添加
stdin=PIPE
,如我的回答所示<如果您使用
.communicate()
,则code>bufsize=0是不必要的,但在这里它也不会有什么坏处。谢谢,我按照您所说的那样使用了管道,它起到了作用。只需删除\r\n.@J.F.Sebastian我提供了最新的代码,它可以工作,非常感谢。