我是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。
答案 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}
)。