Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 非默认shell命令的子进程_Python_Linux_Shell_Subprocess - Fatal编程技术网

Python 非默认shell命令的子进程

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,

我在使用子流程时遇到问题。我想做的是:使用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)
错误说明:
没有这样的文件或目录:“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.