Ubuntu 20.04下通过Python调用PowerShell模块的实现问题
解决Python调用PowerShell执行模块的问题
你的思路方向是对的,但原代码里有几个关键细节没处理好,导致命令没被PowerShell正确执行,我来帮你梳理和修正:
原代码的核心问题
- PowerShell需要收到**换行符
\n**才会执行输入的命令,你写的命令末尾没有加换行,PowerShell一直在等待输入结束 - 写入
stdin后没有调用flush(),导致命令还停留在缓冲区,没发送给PowerShell进程 time.sleep(2)属于不可靠的等待方式,完全没必要,子进程启动后只要输入流就绪就能接收命令
修正后的Python代码
下面是可以正常工作的版本,我加入了必要的换行、flush操作,还优化了输出文件名避免内容覆盖:
import subprocess import time # 启动PowerShell进程,推荐用列表形式传命令,避免shell=True的安全风险 p = subprocess.Popen( ["pwsh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, cwd="./" # 这里指定模块所在的目录,确保PowerShell能找到MyModule.psd1 ) # 导入模块:命令末尾加\n,然后flush确保发送到PowerShell p.stdin.write("Import-Module ./MyModule.psd1\n") p.stdin.flush() # 循环执行模块,比如执行5次 execution_times = 5 for idx in range(execution_times): # 每次输出到不同文件,防止内容被覆盖 output_file = f"result_{idx}.txt" # 构造命令,记得加\n结尾触发执行 run_command = f"MyModule -param 'param_val' -Quiet > {output_file}\n" p.stdin.write(run_command) p.stdin.flush() # 如果模块执行需要时间,可以加短暂等待,根据实际情况调整时长 time.sleep(1) # 关闭输入流,等待PowerShell进程完成所有任务 p.stdin.close() stdout, stderr = p.communicate() # 检查执行过程中的错误和输出 if stderr: print(f"PowerShell执行错误:\n{stderr}") if stdout: print(f"PowerShell输出信息:\n{stdout}")
更简洁的替代方案
其实你可以把所有PowerShell逻辑写成一个独立的脚本,这样调试和维护更方便,Python只需要调用这个脚本即可:
- 创建
run_module.ps1文件:
# 导入模块 Import-Module ./MyModule.psd1 # 循环执行模块,这里设置执行5次 for ($i = 0; $i -lt 5; $i++) { MyModule -param 'param_val' -Quiet > "result_$i.txt" }
- Python调用脚本:
import subprocess result = subprocess.run( ["pwsh", "-f", "run_module.ps1"], cwd="./", capture_output=True, text=True ) # 查看执行结果 if result.stderr: print(f"错误信息:\n{result.stderr}") print(f"输出信息:\n{result.stdout}")
这种方式的好处是,你可以先直接在终端运行pwsh run_module.ps1验证PowerShell逻辑是否正确,再用Python调用,排查问题会更高效。
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

