【问题标题】:How is it possible to send commands to other program from python?如何从 python 向其他程序发送命令?
【发布时间】:2023-09-10 09:27:02
【问题描述】:

问题是:我需要启动一个程序并从 python 发送命令。 例如,它可能是 cmd,我将路径发送到 cd 和 dir 包含(在 Windows 上工作)。 我尝试了很多方法,但仍然找不到解决方案。

我不明白为什么即使在最简单的示例上它也不起作用。 我得出的结论是 subprocess.Popen 可能是实现我目标的最佳方式。 这是我尝试过的。

在任务的第一个块中,程序只打印python文件目录的包含而不是给定的,在第二个块中由于某种原因它什么也不打印

请问有人知道如何正确操作吗?

from subprocess import Popen, PIPE


if __name__ == "__main__":

    path_for_dir = "C:\\Users\\Documents"

    class Console:
        def __init__(self):
            command = r"dir"
            self.console = Popen(
                command, stdin=PIPE, stdout=PIPE, shell=True, text=True
            )

        def read_output(self):
            result = []
            for line in self.console.stdout:
                result.append(line)
            for line in result:
                print(line)

        def cmd(self, cmd_string):
            self.console.stdin.write(cmd_string)
            self.console.stdin.close()

    c = Console()
    c.cmd(f"{path_for_dir}")
    print(c.read_output())

    print(f"NEXT")

    p = Popen(
        ["grep", "n"],
        stdout=PIPE,
        stdin=PIPE,
        stderr=PIPE,
        shell=True,
        universal_newlines=True,
    )
    p.stdin.write("one")
    p.stdin.write("two")
    p.stdin.write("three")
    testresult = p.communicate()[0]
    print(f"{testresult=}")

【问题讨论】:

  • 您实际上想要发送什么命令,您需要返回什么输出?如果您真的想阅读目录列表,请使用os.listdiros.scandirPython documentation 建议你应该使用subprocess.run,除非你需要做一些复杂的事情。
  • Nekomatic,谢谢你的评论,我试图用最简单的例子解释我需要什么,但实际上我需要启动另一个应用程序并从 python 命令一个接一个地发送执行

标签: python cmd subprocess popen


【解决方案1】:
  1. 您根本没有在 1-2-3 示例中编写换行符。所有 grep 看到的都是onetwothree。 (也就是说,onetwothree 仍将匹配 n,但我假设您确实指的是不同的行,因为您有三个不同的写入调用。)
  2. 除非需要,否则不应使用shell=True。您可以使用shutil.which() 来查找类似于 shell 的命令。
from subprocess import Popen, PIPE
from shutil import which

p = Popen(
    [which("grep"), "n"],
    stdout=PIPE,
    stdin=PIPE,
    stderr=PIPE,
    universal_newlines=True,
)
p.stdin.write("one\n")
p.stdin.write("two\n")
p.stdin.write("three\n")
testresult = p.communicate()[0]
print(f"{testresult=}")

打印出来

testresult='one\n'

【讨论】:

  • 谢谢,但我复制了你的代码,不知何故它对我不起作用。它返回一个 TypeError :预期的 str、字节或 os.PathLike 对象,而不是 NoneType,... which("grep")=None which("cmd")='C:\\Windows\\system32\\cmd.EXE' which("python")='C:\\Users\\olgas\\Documents\ \interpreter\\Scripts\\python.EXE'
  • 好吧,我假设你的路径上有grep,因为它肯定不是 Windows 中的默认命令。对于 shell 内部命令,您将需要 shell=True