我在使用子进程时遇到问题。这是我想要做的:使用python打开一个shell,并调用“bluetoothctl”(来自bluez),然后在'bluez'程序下发送/读取其他命令,如“help”。但是,问题是系统不知道'help'命令,因为默认情况下它不受shell支持。它由'bluez'支持。
我的代码:
import subprocess as sub
cmd_line = 'bluetoothctl'
cmd2 = 'help'
open_blue = sub.Popen(cmd_line, shell=True, stdout=sub.PIPE, stderr=sub.STDOUT)
out = open_blue.communicate()[0]
print (out)
open_blue = sub.Popen(cmd2, stdout=sub.PIPE, stderr=sub.STDOUT)
out = open_blue.communicate()[0]
print (out)
错误说:No such file or directory: 'help'
答案 0 :(得分:0)
bluetoothctl
读取命令并写入响应。因此,您应该将其写入help
进程的标准输入,而不是创建尝试执行bluetoothctl
的新进程。
我没有此命令可用,但这里有一个完整的,自包含的示例python
本身,它也接受了#34;帮助"命令:
import subprocess as sub
p = sub.Popen(["python", "-i"], stdin=sub.PIPE, stdout=sub.PIPE);
print("The process said: " + p.communicate("help")[0])
执行时,您将获得python提示符,然后执行以下操作:
The process said: Type help() for interactive help, or help(object) for help about object.
如果您在help
提示中输入python -i
,这正是您所获得的。
答案 1 :(得分:0)
我手头没有BlueZ堆栈。测试,但如果它适用于常规STDOUT / STDIN,你也可以管道STDIN,并使用communicate()
发送你的命令:
bluetoothctl
但是如果open_blue = subprocess.Popen(["bluetoothctl"], shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
while True: # lets wait for 'user' prompt
line = open_blue.stdout.readline().rstrip()
if line.endswith("#"): # this is the prompt, presumably, so stop reading STDOUT
break
print(line + "\n") # print the subprocesses STDOUT
open_blue.stdin.write("help\n") # send the `help` command
while True: # lets repeat the above process
line = open_blue.stdout.readline().rstrip()
if line.endswith("#"): # this is the prompt, presumably, so stop reading STDOUT
break
print(line + "\n") # print the subprocesses STDOUT
# now you can issue another command... and so on.
期望连续流(即充当子shell),则ref
可能不是正确的方法,因为它实质上等待子进程完成向STDOUT发送数据,然后将命令发送到STDIN并关闭它,然后等待STDOUT / STDERR并关闭它们 - 有效地使它对向子进程发送单个命令很有用。如果您要向ComVisible(true)
进程发出各种命令,则可能必须为其编写自己的处理程序。有点像:
导入子流程
[ComVisible(true)]
[ProgId("One.Two.Three.SomeClass")]
public class SomeClass1
{
public SomeClass2 SomeFunction(string text)
{
return new SomeClass2 { Text = text };
}
}
[ComVisible(true)]
public class SomeClass2
{
public string Text { get; set; }
}