Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
868 views
in Technique[技术] by (71.8m points)

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

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

import subprocess
subprocess.call(["C:Usersgu2124Desktophelloworld.ps1"])

As was suggested here Run PowerShell function from Python script but 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

import subprocess
subprocess.Popen(["C:Usersgu2124Desktophelloworld.ps1"], stdout=sys.stdout)

and I get this error

Traceback (most recent call last):
  File "C:Usersgu2124Desktoppstest.py", line 5, in <module>
    subprocess.Popen(["C:Usersgu2124Desktophelloworld.py1"], stdout=sys.stdout)
  File "C:Python27libsubprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:Python27libsubprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
  File "<string>", line 523, in __getattr__
  File "C:Program FilesPyScripterLib
pyc.zip
pyccore
etref.py", line 150, in __getattr__
    return syncreq(self, consts.HANDLE_GETATTR, name)
  File "C:Program FilesPyScripterLib
pyc.zip
pyccore
etref.py", line 71, in syncreq
    return conn.sync_request(handler, oid, *args)
  File "C:Program FilesPyScripterLib
pyc.zip
pyccoreprotocol.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.PIPE so I tried this

import subprocess
subprocess.Popen(["C:Usersgu2124Desktophelloworld.ps1"], stdout=subprocess.PIPE)

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

import subprocess
p = subprocess.Popen(["powershell","C:Usersgu2124Desktophelloworld.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

<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

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

$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:

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:Python27libsubprocess.py", line 701, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:Python27libsubprocess.py", line 848, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
UnsupportedOperation: fileno 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  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()
    

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

C:UsersMacEwinDesktop>python helloworld.py
Hello World

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...