2014-02-21 339 views
4

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

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

正如这里Run PowerShell function from Python script建议,但我发现这个等待程序先执行,不给输出,所以我发现我需要使用subprocess.Popen()因为在这里suggusted Use Popen to execute a Powershell script in Python, how can I get the Powershell script's output and update it to web page?所以我试过这种

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

,我得到这个错误

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' 

我不能完全肯定这是什么意思,但是从我认为在阅读AttributeError: StringIO instance has no attribute 'fileno'之后我明白,这是因为我错误地搞错了stdout。我看着周围的更多,我发现这个Why won't my python subprocess code work?其中的答案说要用stdout=subprocess.PIPE,所以我想这

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

也没有给我输出 最后,我看到这个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 

我认为这可能是因为我最初试图从命令行运行powershell脚本,所以必须先打开powershell。当我直接输入这些命令在命令行中它工作的方式应该,但是当我通过Python脚本来运行它,它给这个

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

这是一种进步我想,但不是“世界,你好”我是期待。 我不知道我应该尝试下一步做些什么才能使其发挥作用。任何帮助将不胜感激

而且,如果我使用PowerShell脚本这里需要它

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

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

编辑:我尝试升级到Python 3.3像第一个答案是建议,但我仍然可以”让它工作。我用命令p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)并深信该文件是存在的,但我得到这个错误:

​​
+0

当您编写'print p.communicate'时,将打印出方法对象,而不是打印出运行方法的结果。您需要将其更改为'print p.communciate()'以获得您想要的结果。 – NuclearPeon

+0

您也不会导入sys模块,这会导致调用sys.stdout失败。 UnsupportedOperation意味着你的操作系统不支持fileno()。如果你看这里:http://forums.devshed.com/python-programming-11/python27-pyserial-windows-broken-select-fileno-827240.html,它指的是提到fileno()的文档只是unix 。如果'subprocess.Popen()'不适合你,你可以尝试'os.system()',尽管它已被弃用。 – NuclearPeon

回答

8
  1. 确保你可以运行PowerShell脚本(这是默认禁用)。可能你已经做到了。http://technet.microsoft.com/en-us/library/ee176949.aspx

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

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

这个代码是基于python3.4(或任何3.x系列的解释),但应也在python2.x系列上工作。

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

我没有安装的Python 2.7,但在Python 3.3调用Popenstdout设置为sys.stdout工作就好了。尽管如此,我还没有逃过路上的反斜杠。

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

我试着改变我的代码,像你建议并升级到Python 3.3,但它仍然无法正常工作......我编辑了问题以反映我的新输出和代码 – user3282276