我正在尝试从Python运行Powershell子流程。我需要将Python中的Powershell代码发送到子进程。我到目前为止:
import subprocess
import time
args = ["powershell", "-NoProfile", "-InputFormat None", "-NonInteractive"]
startTime = time.time()
process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.stdin.write("Write-Host 'FINISHED';".encode("utf-8"))
result = ''
while 'FINISHED' not in result:
result += process.stdout.read(32).decode('utf-8')
if time.time() > startTime + 5:
raise TimeoutError(result)
print(result)
这次超时,因为没有任何东西被写入stdout。我认为Write-Host
cmdlet永远不会被执行。即使是简单的bash / Cygwin代码echo "Write-Host 'FINISHED';" | powershell
似乎也无法完成这项任务。
为了进行比较,使用-Command
标志发送代码块可以正常工作。
如何说服Powershell运行我发送给stdin的代码?
答案 0 :(得分:3)
您可以考虑以下几点:
在您为其提供应执行的脚本文件的模式下调用PowerShell。在调用子进程之前编写此脚本文件。使用PowerShell的-File <FilePath>
参数(参见docs)
如果您真的想使用stdin
技术,可能会在命令后丢失换行符。如果这没有帮助,您可能需要发送另一个控制字符,告诉PowerShell达到输入EOF。您肯定需要查阅PowerShell文档以了解如何在stdin上“终止”命令。你绝对需要的一件事是-Command -
论点:The value of Command can be "-", a string. or a script block. If the value of Command is "-", the command text is read from standard input.
你可能也想看看这个小小的黑客:https://stackoverflow.com/a/13877874/145400
如果您只想执行一个命令,可以使用out, err = subprocess.communicate(in)
答案 1 :(得分:2)
我遇到了类似的任务,但我能够解决它。
首先是我的示例代码:
import subprocess
args = ["powershell.exe", "-Command", r"-"]
process = subprocess.Popen(args, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
process.stdin.write(b"$data = Get-ChildItem C:\\temp\r\n")
process.stdin.write(b"Write-Host 'Finished 1st command'\r\n")
process.stdin.write(b"$data | Export-Clixml -Path c:\\temp\state.xml\r\n")
process.stdin.write(b"Write-Host 'Finished 2nd command'\r\n")
output = process.communicate()[0]
print(output.decode("utf-8"))
print("done")
主要问题是正确的参数列表 args 。需要使用 -Command -flag启动powershell,然后按Jan-Philipp所示的“ - ”启动。
另一个谜团是执行这些东西所需的行尾字符。 \ r \ n 效果很好。
获取Powershell的输出仍然是一个问题。但如果你不关心实时,你可以通过调用
完成所有执行后收集输出output = process.communicate()[0]
但是,活跃的Powershell将在之后终止。