簡體   English   中英

在python腳本中運行powershell腳本,如何讓python在運行時打印powershell輸出

[英]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 
  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

我沒有安裝 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM