与命令行程序交互

时间:2018-07-07 08:46:05

标签: python real-time popen pexpect

我想简化命令行程序并实时获取输出。我尝试过pexpect,Popen。但是都失败了。

我有一个这样的C程序。

#include "stdio.h"
#include "stdlib.h"
int main(int argc, char **argv)
{
int x;
printf("hello");
scanf("%d",  &x);
printf("x=%d",x);
}

我用gcc编译了程序,输出是文件'a.out'。

'a.out'可以像bash shell一样运行。

当我在终端中运行'a.out'时,我将得到一个'hello',然后等待我的输入。

我希望'a.out'与python交互并进行pexpect。 问题:

  1. 使用Pexpect

    由于我想匹配任何东西,因此我使用pexpect(".*")pexpect(r".*"),但是before和after不显示任何内容(b''),而pexpect('hello')可以正常工作。

    import pexpect
    x = pexpect.spawn('./a.out')
    x.expect('.*')
    print(x.before, x.after)
    x.expect(r'.*')
    print(x.before, x.after)
    x.expect('hello')
    print(x.before, x.after)
    
  2. 使用Popen

    import subprocess
    x = subprocess.Popen('./a.out', shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)
    

t.poll()始终为无,而t.read()或t.readline()将使程序挂起。

注意,它具有字符串“ hello”,但没有新行。

任何基于行的方法都不会成功。

1 个答案:

答案 0 :(得分:2)

您可能想通过在所有printf()输出之后添加\ n来使C程序更易于处理readline()期望的方法

#include "stdio.h"
#include "stdlib.h"
int main(int argc, char **argv)
{
int x;
printf("hello\n");
scanf("%d",  &x);
printf("x=%d\n",x);
}

然后您可以编写这样的Python程序。

import pexpect
x = pexpect.spawn('./a.out')
print(x.readline())     # reads 'hello'
x.sendline('6')         # sends 6 with \n
print(x.readline())     # reads 6
print(x.readline())     # reads x=6

输出

b'hello\r\n'
b'6\r\n'
b'x=6\r\n'

可以使用str()或decode()函数将输出从字节转换为字符串

出于您的目的,使用cmd模块将更加有用。这只是其工作方式的示例示例。

import cmd, os

class MyCli(cmd.Cmd):
    intro = "Welcome to my shell"
    prompt = '>'

    def emptyline(self):           # Do nothing for empty line
        pass

    def do_mycmd(self, user_cmd):  # When user enters mycmd execute a.out
        os.system("./a.out")

    def default(self, user_cmd):   # When user gives input that is not command print message
        print("Unknown command")

    def do_exit(self, user_cmd):   # Exit command
        print("goodbye")
        return True

ins1 = MyCli()
ins1.cmdloop()

输出

Welcome to my shell
>
>mycmd
hello
25
x=25
>
>exit
goodbye