在python脚本中运行powershell脚本,如何让python在运行时打印powershell输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21944895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:55:26  来源:igfitidea点击:

Running powershell script within python script, how to make python print the powershell output while it is running

pythonwindowspython-2.7powershellstdout

提问by user3282276

I am writing a python script which checks various conditions and runs a powershell script accordingly to help me automate migration from windows XP to windows 7. The powershell script gives its own output giving the user updates as to what is happening. I would like to take the output of the powershell script and print it as output of the python script. I have looked around at some questions which seem to want to do the same thing but they don't seem to be working for me. Initially I tried using

我正在编写一个 python 脚本,它检查各种条件并相应地运行一个 powershell 脚本,以帮助我自动从 Windows XP 迁移到 Windows 7。powershell 脚本提供自己的输出,让用户更新正在发生的事情。我想获取 powershell 脚本的输出并将其打印为 python 脚本的输出。我环顾了一些似乎想做同样事情的问题,但它们似乎对我不起作用。最初我尝试使用

import subprocess
subprocess.call(["C:\Users\gu2124\Desktop\helloworld.ps1"])

As was suggested here Run PowerShell function from Python scriptbut I found out that this waits for the program to execute first and does not give output so I found out I need to use subprocess.Popen()as was suggusted here Use Popen to execute a Powershell script in Python, how can I get the Powershell script's output and update it to web page?so I tried this

正如这里建议的那样从 Python 脚本运行 PowerShell 函数,但我发现这会等待程序首先执行并且不提供输出,所以我发现我需要subprocess.Popen()按照此处的建议使用使用Popen在 Python 中执行 Powershell 脚本,如何获取 Powershell 脚本的输出并将其更新到网页?所以我试过这个

import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=sys.stdout)

and I get this error

我收到这个错误

Traceback (most recent call last):
  File "C:\Users\gu2124\Desktop\pstest.py", line 5, in <module>
    subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.py1"], stdout=sys.stdout)
  File "C:\Python27\lib\subprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
  File "<string>", line 523, in __getattr__
  File "C:\Program Files\PyScripter\Lib\rpyc.zip\rpyc\core\netref.py", line 150, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "C:\Program Files\PyScripter\Lib\rpyc.zip\rpyc\core\netref.py", line 71, in syncreq
    return conn.sync_request(handler, oid, *args)
  File "C:\Program Files\PyScripter\Lib\rpyc.zip\rpyc\core\protocol.py", line 434, in sync_request
    raise obj

AttributeError: DebugOutput instance has no attribute 'fileno'

I'm not completely sure what this means but from what I think I understand after reading this AttributeError: StringIO instance has no attribute 'fileno'is that it is because I am messing with the stdout incorrectly. I looked a around more and I found this Why won't my python subprocess code work?where the answers said to use stdout=subprocess.PIPEso I tried this

我不完全确定这是什么意思,但从我在阅读此AttributeError: StringIO instance has no attribute 'fileno'后的理解来看,这是因为我错误地弄乱了标准输出。我环顾四周,发现为什么我的 python 子进程代码不起作用?答案说使用的地方stdout=subprocess.PIPE所以我尝试了这个

import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)

which also does not give me output Finally I saw this http://www.pythonforbeginners.com/os/subprocess-for-system-administratorsand changed my code to this

这也没有给我输出最后我看到了这个http://www.pythonforbeginners.com/os/subprocess-for-system-administrators并将我的代码更改为此

import subprocess
p = subprocess.Popen(["powershell","C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)
print p.communicate

I thought that it may because I am initially trying to run a powershell script from the command line so I have to open powershell first. When I type these commands directly into the command line it works the way it should but when I run it through the python script it gives this

我认为这可能是因为我最初尝试从命令行运行 powershell 脚本,所以我必须先打开 powershell。当我直接在命令行中键入这些命令时,它会按照应有的方式工作,但是当我通过 python 脚本运行它时,它会给出这个

<bound method Popen.communicate of <subprocess.Popen object at 0x00000000026E4A90>>

which is an improvement I guess but not the "Hello world" I was expecting. I have no idea what I should try to do next to get this to work. Any help would be greatly appreciated

我猜这是一个改进,但不是我期待的“Hello world”。我不知道接下来我应该尝试做什么才能让它发挥作用。任何帮助将不胜感激

Also if the powershell script I am using is needed here it is

此外,如果这里需要我正在使用的 powershell 脚本,它是

$strString = "Hello World"
write-host $strString

function ftest{
$test = "Test"
write-host $test
}

EDIT: I tried upgrading to python 3.3 like was suggested in the first answer but I still can't get it to work. I used the command p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)and am sure the file is there but am getting this error:

编辑:我尝试像第一个答案中建议的那样升级到 python 3.3,但我仍然无法让它工作。我使用了该命令p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)并确定该文件在那里,但出现此错误:

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    p = subprocess.Popen(['powershell.exe', "C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=sys.stdout)
  File "C:\Python27\lib\subprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
UnsupportedOperation: fileno 

采纳答案by NuclearPeon

  1. Make sure you can run powershell scripts (it is disabled by default). Likely you have already done this. http://technet.microsoft.com/en-us/library/ee176949.aspx

    Set-ExecutionPolicy RemoteSigned
    
  2. Run this python script on your powershell script helloworld.py:

    # -*- coding: iso-8859-1 -*-
    import subprocess, sys
    
    p = subprocess.Popen(["powershell.exe", 
                  "C:\Users\USER\Desktop\helloworld.ps1"], 
                  stdout=sys.stdout)
    p.communicate()
    
  1. 确保您可以运行 powershell 脚本(默认情况下它是禁用的)。很可能你已经这样做了。http://technet.microsoft.com/en-us/library/ee176949.aspx

    Set-ExecutionPolicy RemoteSigned
    
  2. 在你的 powershell 脚本上运行这个 python 脚本helloworld.py

    # -*- coding: iso-8859-1 -*-
    import subprocess, sys
    
    p = subprocess.Popen(["powershell.exe", 
                  "C:\Users\USER\Desktop\helloworld.ps1"], 
                  stdout=sys.stdout)
    p.communicate()
    

This code is based on python3.4 (or any 3.x series interpreter), though it should work on python2.x series as well.

此代码基于 python3.4(或任何 3.x 系列解释器),但它也适用于 python2.x 系列。

C:\Users\MacEwin\Desktop>python helloworld.py
Hello World

回答by Ansgar Wiechers

I don't have Python 2.7 installed, but in Python 3.3 calling Popenwith stdoutset to sys.stdoutworked just fine. Not before I had escaped the backslashes in the path, though.

我没有安装 Python 2.7,但在 Python 3.3 中Popen使用stdoutset调用可以正常sys.stdout工作。不过,在我逃脱路径中的反斜杠之前。

>>> import subprocess
>>> import sys
>>> p = subprocess.Popen(['powershell.exe', 'C:\Temp\test.ps1'], stdout=sys.stdout)
>>> Hello World
_