传递Popen.communicate()的整数输入参数

时间:2016-01-29 05:21:46

标签: python-2.7 shell popen

我是python的新手,现在我遇到了困难。我正在使用python 2.7。 我试图在shell中自动执行一个我编写python脚本的命令。我必须输入一个整数值给我使用Popen.communicate的shell(输入=' 2')。虽然传递了输入,但它作为字符串传递,子进程需要它作为数值。当我尝试将其作为数字值传递,如Popen.communicate(输入= 2)时,它会抛出以下错误:

  

TypeError:' int'对象没有属性' __ getitem __ '

那么有没有办法将输入作为数值发送?

以下是我使用的代码:

import sys
from subprocess import Popen, PIPE, STDOUT

cmd = ["sudo", "./sbt", "project java-examples", "run"]
proc = Popen(cmd, bufsize=4096, shell=False, stdout=PIPE, stdin=PIPE, stderr=STDOUT)

string = proc.communicate(input='2')
print string[0]
proc.stdin.close()

编辑: 对不起,我在第一时间没有提到这一点。 我的java应用程序有多个主类,因此编译器会询问要执行哪个类,我需要每次都输入相同的数字,这就是为什么我要尝试自动化它。当我传递一个字符串值时,它会抛出numberformatexception。

3 个答案:

答案 0 :(得分:1)

最后我找到了解决方案。 那么解决方案很简单

当我改变了

  

string = proc.communicate(input ='2')

  

string = proc.communicate(input ='2 \ n')

它运作良好。

答案 1 :(得分:0)

您正在调用的./sbt进程需要能够读取字符串并将其转换为整数。不能将本机Python类型发送到只有Popen的子进程。

另一个可能的解决方案是将数据序列化为JSON,YAML,XML,python pickle格式等 - 选择您的标准。但是,当你传递一个整数时,这看起来非常过分。

答案 2 :(得分:0)

管道是Unix中的字节流。没有数字输入 - 只有“字符串”输入(没有数字或其他任何东西 - 只有字节)。

如果您的子进程java进程需要一个数字作为其ascii表示,那么如果子进程从stdin(.communicate(input='2'))读取,则System.in已经正确。如果java进程直接从控制台读取(System.console().readLine()),则stdin=PIPE将无效(在这种情况下,您可能需要提供pty,例如,使用pexpect)。

例如,要从stdin中读取一个整数并将其打印回Java:

import java.util.Scanner;

public class ReadInteger
{
  public static void main(String args[])
  {
    Scanner in = new Scanner(System.in);
    int i = in.nextInt();
    System.out.println("got " + i);
  }
}

通过管道将Python进程中的整数传递给Java进程:

#!/usr/bin/env python2
from subprocess import Popen, PIPE

p = Popen(['java', '-ea', 'ReadInteger'], stdin=PIPE, stdout=PIPE)
output = p.communicate(input='2')[0]
print 'from java {' + output.strip() + '}'

工作正常(输出为from java {got 2})。

如果子进程从控制台读取,它将停止工作:

public class ReadIntegerConsole
{
  public static void main(String args[])
  {
    int i = Integer.parseInt(System.console().readLine());
    System.out.println("got " + i);
  }
}

相同的python脚本导致NullPointerException(并且输出为from java {})因为System.console()在这里为空(stdin被重定向)。如果我们提供伪tty,它就可以工作:

#!/usr/bin/env python2
import pexpect # $ pip install pexpect

child = pexpect.spawn('java -ea ReadIntegerConsole')
child.setecho(False)
child.sendline('2')
child.expect(pexpect.EOF)
child.close()
print "from java {" + child.before.strip() + "}"

工作正常(输出为from java {got 2})。