Python 执行外部程序后可以发送多个输入的脚本

Python script that can send multiple inputs after executing external program

我正在寻找使用 Python 为 Windows 创建一个 diskpart 脚本。

我需要 运行 diskpart 然后在程序执行后发出额外的命令一系列输入如下。我最终会把它放在一个循环中,这样它就可以对一系列磁盘完成。

我已尝试按以下方式执行此操作。

在下面的示例中,我能够执行 diskpart 然后 运行 第一个命令 "select disk 1" 然后它终止。我希望能够发送额外的命令来完成准备磁盘的过程,该怎么做? diskpart 除了从文件中读取外,不接受可以促进这一点的参数,但我想在 Windows 2012 PowerShell cmdelts 上避免这种情况,使这更容易实现。

import subprocess

from subprocess import Popen, PIPE, STDOUT
p = Popen(['diskpart'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'select disk 1')[0]
print(grep_stdout.decode())

正在寻找与

类似的内容
from subprocess import Popen, PIPE, STDOUT
p = Popen(['diskpart'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'select disk 1')[0]

- run command
- run command
- run command
- run command 
- run command
- run command
- run command

print(grep_stdout.decode())

我在下面尝试了以下操作,实际上执行了 diskpart,然后还 运行s 命令 "select disk 1" 并在之后退出,我相信这不是发送输入的正确方式,但更多如果我可以继续发送后续命令,我正在努力实现的目标。

import subprocess
from subprocess import Popen, PIPE, STDOUT
p = Popen(['diskpart'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'select disk 1')[0]

我认为您在使用 communicate 时遇到问题 - 它将数据发送到进程,然后等待它完成。 (参见 Communicate multiple times with a process without breaking the pipe?

我不确定这是否会有帮助,但我根据链接的答案编写了一个批处理脚本。

test.bat:

@echo off

set /p animal= "What is your favourite animal? " 
echo %animal%

set /p otheranimal= "What is another awesome animal? "
echo %otheranimal%

set "animal="
set "otheranimal="

test.py:

import time
from subprocess import Popen, PIPE

p = Popen(["test.bat"], stdin=PIPE)

print("sending data to STDIN")
res1 = p.stdin.write("cow\n")
time.sleep(.5)
res2 = p.stdin.write("velociraptor\n")

这通过将数据发送到标准输入来工作,而不是等待进程完成。

我不是 windows 专家,所以如果 diskpart 中的输入处理与批处理文件的标准输入不同,我深表歉意。

在 Tims 的帮助下,我能够执行以下操作来让我的脚本正常工作。

import time
from subprocess import Popen, PIPE

p = Popen(["diskpart"], stdin=PIPE)
print("sending data to STDIN")
res1 = p.stdin.write(bytes("select disk 2\n", 'utf-8'))
time.sleep(.5)
res2 = p.stdin.write(bytes("ATTRIBUTES DISK CLEAR READONLY\n", 'utf-8'))
time.sleep(.5)
res3 = p.stdin.write(bytes("online disk noerr\n", 'utf-8'))
time.sleep(.5)
res4 = p.stdin.write(bytes("clean\n", 'utf-8'))
time.sleep(.5)
res5 = p.stdin.write(bytes("create part pri\n", 'utf-8'))
time.sleep(.5)
res6 = p.stdin.write(bytes("select part 1\n", 'utf-8'))
time.sleep(.5)
res7 = p.stdin.write(bytes("assign\n", 'utf-8'))
time.sleep(.5)
res8 = p.stdin.write(bytes("FORMAT FS=NTFS QUICK \n", 'utf-8'))
time.sleep(.5)

您还可以创建一个文本文件,其中包含由换行符分隔的 diskpart 命令,然后是 运行 diskpart /s 'filename'。像这样:

from subprocess import Popen, PIPE
import os

with open("temp.txt", "wt") as file:
    file.write("command\ncommand\ncommand")
p = Popen(["diskpart","/s","temp.txt"], stdin=PIPE)
os.remove("temp.txt")

这个解决方案可以防止在程序准备好之前写入终端的可能问题。此外,如果 diskpart 要求进一步说明并改为获取下一个命令,它可能会解决潜在问题。

来源:https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/diskpart-scripts-and-examples