非默认shell命令的子进程

时间:2017-06-24 00:40:22

标签: python linux shell subprocess

我在使用子进程时遇到问题。这是我想要做的:使用python打开一个shell,并调用“bluetoothctl”(来自bluez),然后在'bluez'程序下发送/读取其他命令,如“help”。但是,问题是系统不知道'help'命令,因为默认情况下它不受shell支持。它由'bluez'支持。 here is what i wanna do

我的代码:

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'

我想知道这里有什么问题。 感谢。

2 个答案:

答案 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; }
}