[英]Running powershell script within python script, how to make python print the powershell output while it is running
我正在編寫一個 python 腳本,它檢查各種條件並相應地運行一個 powershell 腳本,以幫助我自動從 windows XP 遷移到 windows 7。powershell 腳本提供自己的輸出,讓用戶更新正在發生的事情。 我想獲取 powershell 腳本的輸出並將其打印為 python 腳本的輸出。 我環顧了一些似乎想做同樣事情的問題,但它們似乎對我不起作用。 最初我嘗試使用
import subprocess
subprocess.call(["C:\Users\gu2124\Desktop\helloworld.ps1"])
正如這里所建議的從 Python 腳本運行 PowerShell 函數,但我發現這會等待程序首先執行並且不提供輸出,所以我發現我需要使用 subprocess.Popen subprocess.Popen()
建議這里使用 Popen 執行Python 中的 Powershell 腳本,如何獲取 Powershell 腳本的輸出並將其更新到網頁? 所以我嘗試了這個
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'后的理解來看,這是因為我錯誤地弄亂了標准輸出。 我環顧四周,發現為什么我的 python 子進程代碼不起作用? 答案說使用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>>
我猜這是一個改進,但不是我期待的“Hello world”。 我不知道接下來我應該怎么做才能讓它發揮作用。 任何幫助將不勝感激
此外,如果這里需要我使用的 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)
並確定文件在那里但我收到此錯誤:
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
確保您可以運行 powershell 腳本(默認情況下禁用)。 您可能已經這樣做了。 http://technet.microsoft.com/en-us/library/ee176949.aspx
Set-ExecutionPolicy RemoteSigned
在你的 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
我沒有安裝 Python 2.7,但在 Python 3.3 中調用Popen
並將stdout
設置為sys.stdout
工作得很好。 不過,在我逃脫了路徑中的反斜杠之前。
>>> import subprocess
>>> import sys
>>> p = subprocess.Popen(['powershell.exe', 'C:\\Temp\\test.ps1'], stdout=sys.stdout)
>>> Hello World
_
除了前面的答案之外,我還有一些建議可以使您的代碼更具可移植性。
除了將ExecutionPolicy
全局設置為RemoteSigned
(這會帶來一些安全問題),您可以使用它來僅為 Python 腳本創建的 PowerShell 實例設置它:
import subprocess, sys
p = subprocess.Popen('powershell.exe -ExecutionPolicy RemoteSigned -file "hello world.ps1"', stdout=sys.stdout)
p.communicate()
請注意允許 PowerShell 腳本的路徑/文件名包含空格的引號。
此外,如上例所示,您可以使用相對路徑來調用您的 PowerShell 腳本。 該路徑相對於您的 Python 工作區目錄。
這就是我從 Popen 獲取輸出的方式
p = subprocess.Popen(["powershell","C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)
p_out, p_err = p.communicate()
print(p_out)
來自 Popen.communicate() 上的文檔。 該函數返回一個元組(stdout_data,stderr_data)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.