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

时间:2015-03-10 22:02:00

标签: python windows input subprocess command-prompt

我希望使用Python为Windows创建一个diskpart脚本。

我需要运行diskpart,然后在程序执行后发出其他命令,下面是一系列输入。我最终将它放在一个循环中,因此可以对一系列磁盘进行处理。

  • SELECT DISK 1
  • ATTRIBUTES DISK CLEAR READONLY
  • ONLINE DISK noerr
  • CLEAN
  • CREATE PART PRI
  • SELECT PART 1
  • ASSIGN
  • FORMAT FS = NTFS QUICK LABEL =“New Volume”

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

在下面的示例中,我能够执行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然后还运行命令“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]

3 个答案:

答案 0 :(得分:1)

我认为你在这里遇到了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")

这可以通过将数据发送到stdin来实现,但不是等待进程完成。

我不是Windows专家,所以如果diskpart中的输入处理与批处理文件的标准输入不同,我会道歉。

答案 1 :(得分:0)

在Tim的帮助下,我能够执行以下操作以使我的脚本工作。

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)

答案 2 :(得分:0)

您也可以使用由换行符分隔的 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

相关问题