为 Popen.communicate() 传递整数输入参数
Pass integer input argument for Popen.communicate()
我是 python 的新手,现在我遇到了一些问题。我正在使用 python 2.7。
我正在尝试自动执行 shell 中的命令,我为此编写了 python 脚本。我必须向我正在使用 Popen.communicate(input='2') 的 shell 输入一个整数值。尽管传递了输入,但它是作为字符串传递的,子流程需要它作为数值。当我尝试将其作为 Popen.communicate(input=2) 之类的数字值传递时,它会抛出以下错误:
TypeError: 'int' object has no attribute '__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 应用程序有多个主要的 classes 因此编译器询问要执行哪个 class ,我每次都需要输入相同的数字,这就是我试图自动化它的原因.当我传递一个字符串值时,它会抛出数字格式异常。
您正在调用的 ./sbt
进程需要能够读取字符串并将其转换为整数。无法将本机 Python 类型发送到仅具有 Popen
.
的子进程
另一种可能的解决方案是将数据序列化为 JSON、YAML、XML、python pickle 格式等 - 选择您的标准。但是,当您传递一个整数时,这似乎太过分了。
管道是 Unix 中的字节流。没有数字输入——只有 "string" 输入(没有数字或其他任何东西——只有字节)。
如果您的子进程 java 需要一个数字作为它的 ascii 表示,那么如果子进程从标准输入 (System.in
) 读取,.communicate(input='2')
已经是正确的。如果 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()
在这里为空(重定向标准输入)。如果我们提供一个伪终端就可以工作:
#!/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}
)。
我终于找到了解决办法。
好吧,解决这个问题的方法非常简单
当我改变的时候
string = proc.communicate(input='2')
至
string = proc.communicate(input='2\n')
它运行良好。
我是 python 的新手,现在我遇到了一些问题。我正在使用 python 2.7。 我正在尝试自动执行 shell 中的命令,我为此编写了 python 脚本。我必须向我正在使用 Popen.communicate(input='2') 的 shell 输入一个整数值。尽管传递了输入,但它是作为字符串传递的,子流程需要它作为数值。当我尝试将其作为 Popen.communicate(input=2) 之类的数字值传递时,它会抛出以下错误:
TypeError: 'int' object has no attribute '__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 应用程序有多个主要的 classes 因此编译器询问要执行哪个 class ,我每次都需要输入相同的数字,这就是我试图自动化它的原因.当我传递一个字符串值时,它会抛出数字格式异常。
您正在调用的 ./sbt
进程需要能够读取字符串并将其转换为整数。无法将本机 Python 类型发送到仅具有 Popen
.
另一种可能的解决方案是将数据序列化为 JSON、YAML、XML、python pickle 格式等 - 选择您的标准。但是,当您传递一个整数时,这似乎太过分了。
管道是 Unix 中的字节流。没有数字输入——只有 "string" 输入(没有数字或其他任何东西——只有字节)。
如果您的子进程 java 需要一个数字作为它的 ascii 表示,那么如果子进程从标准输入 (System.in
) 读取,.communicate(input='2')
已经是正确的。如果 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()
在这里为空(重定向标准输入)。如果我们提供一个伪终端就可以工作:
#!/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}
)。
我终于找到了解决办法。 好吧,解决这个问题的方法非常简单
当我改变的时候
string = proc.communicate(input='2')
至
string = proc.communicate(input='2\n')
它运行良好。