Python 非默认shell命令的子进程
我在使用子流程时遇到问题。我想做的是:使用python打开一个shell,调用“bluetoothctl”(来自bluez),然后在“bluez”程序下发送/读取其他命令,如“help”。但是,问题是系统不知道“help”命令,因为默认情况下shell不支持该命令。它由“bluez”支持。 我的代码:Python 非默认shell命令的子进程,python,linux,shell,subprocess,Python,Linux,Shell,Subprocess,我在使用子流程时遇到问题。我想做的是:使用python打开一个shell,调用“bluetoothctl”(来自bluez),然后在“bluez”程序下发送/读取其他命令,如“help”。但是,问题是系统不知道“help”命令,因为默认情况下shell不支持该命令。它由“bluez”支持。 我的代码: import subprocess as sub cmd_line = 'bluetoothctl' cmd2 = 'help' open_blue = sub.Popen(cmd_line,
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)
错误说明:没有这样的文件或目录:“help”
我想知道这里怎么了。
谢谢。
bluetoothctl
读取命令并写入响应。因此,您应该将其写入bluetoothctl
进程的stdin,而不是创建一个尝试执行help
的新进程
我没有这个命令可用,但这里有一个完整的、自包含的示例,它包含python
本身,它也接受一个“help”命令:
执行时,您将得到python提示,然后:
The process said: Type help() for interactive help, or help(object) for help about object.
如果您在
python-i
提示符中键入help
,这正是您得到的结果。我手头没有BlueZ堆栈。要进行测试,但前提是它与常规STDOUT/STDIN一起工作,您也可以使用管道STDIN,并使用Popen.communicate()
发送命令:
import subprocess
open_blue = subprocess.Popen(["bluetoothctl"], shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
out, err = open_blue.communicate("help")
print(out)
但是,如果bluetoothctl
需要连续流(即充当子shell),那么communicate()
可能不是正确的方法,因为它实际上是等待子进程完成向STDOUT发送数据,然后将您的命令发送到STDIN并关闭它,然后等待STDOUT/STDERR并关闭它们——这有效地使它对于向子进程发送单个命令非常有用。如果要向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.
我想知道[“python”、“-i”]在这里做什么?“-i”使python启动其REPL,即使它从管道而不是终端获取数据。没有它,它将读取脚本而不是repl命令。比较
echo-help|python
和echo-help|python-i
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.