我試圖運行一個for循環,它遍歷命令輸出的每一行。例如:在python中使用exec for循環
for line in exec 'lspci | grep VGA':
count = count + 1
嘗試獲取安裝在系統中的視頻卡數量。但是它似乎沒有在for循環行上排列語法。
我必須爲exec導入一個庫嗎?還是我用它錯了?或兩者?
由於
我試圖運行一個for循環,它遍歷命令輸出的每一行。例如:在python中使用exec for循環
for line in exec 'lspci | grep VGA':
count = count + 1
嘗試獲取安裝在系統中的視頻卡數量。但是它似乎沒有在for循環行上排列語法。
我必須爲exec導入一個庫嗎?還是我用它錯了?或兩者?
由於
exec
執行Python代碼,而不是外部命令。您正在尋找subprocess.Popen()
:
import subprocess
p = subprocess.Popen('lspci', stdout=subprocess.PIPE)
for line in p.stdout:
if 'VGA' in line:
print line.strip()
p.wait()
在我的盒子,這個打印出
01:00.0 VGA compatible controller: nVidia Corporation GF104 [GeForce GTX 460] (rev a1)
關鍵字exec
執行Python代碼。它不啓動新的進程。
嘗試使用subprocess模塊。
lines = subprocess.check_output(["lspci"]).split('\n')
count = sum('VGA' in line for line in lines)
這可能會起作用,但RHEL5.5似乎隨2.4.3一起發佈,我無法輕鬆升級所有需要部署的系統。雖然 – Danny
你想用popen
(或類似的東西)。 exec
檢查python代碼。例如:
exec('x = 4')
print x # prints 4
而且,你缺少括號,變得無法語法。 exec
是一個函數:
for line in exec('lspci | grep VGA'): # this still does not do what you want
count = count + 1
您可以使用wc -l
搶行數在一杆。
import os
count = os.popen('lspci | grep VGA | wc -l').read()
子進程模塊替換os.popen –
我在Python寫了這個效用函數爲這些類型的目的
的(使用臨時文件的原因是,如果你打開一個子進程,並使用subprocess.PIPE,當標準輸出得到捕獲標準輸出超過64K的數據,蟒蛇只是掛起永遠)
import logging
import tempfile
import subprocess
import os
def getPipedCommandOut(cmd):
"""
cmd - command to execute
gathers output of command (stderr and stdout) into a temp file
returns the output of the command
"""
logging.debug('starting %s' % cmd)
temp = tempfile.TemporaryFile('w+t')
try:
p = subprocess.Popen(cmd, stderr=subprocess.STDOUT,stdout=temp.fileno(), shell=True)
#pid, status = os.waitpid(p.pid,0) #@UnusedVariable
status = p.wait()
temp.seek(0)
out = temp.read()
if status != 0:
raise CommandRunError("COMMAND: %s\tFAILED: %s%s%s" % (cmd, status, os.linesep, out))
logging.debug('finished %s' % cmd)
finally:
temp.close()
return out
然後用你的代碼中使用:
lspciOutput = getPipedCommandOut('lspci | grep VGA')
for line in lspciOutput:
count = count + 1
你的程序(你不能責怪Python)因爲你在從管道讀取任何輸出之前調用'p.wait()'*。您的OS管道緩衝區大小顯然爲64k,因此在寫入其所有輸出之前,程序永遠不會完成。相反,你可以在調用'p.wait()'之前讀取管道輸出*,避免使用臨時文件。或者,您可以使用['subprocess.communicate'](http://docs.python.org/library/subprocess.html#subprocess.Popen。溝通),爲您處理所有這些。 –
同意這是一個點緩衝區大小問題 - 而不是一個python的bug。但我現在喜歡臨時文件解決方法。你認爲它與閱讀和附加管道中的字符串或使用通信有什麼不利嗎? – uncreative
如果您期望*非常*大量的輸出(超過可以合理安裝在RAM中的數量,比如數百兆字節)並且想要將其假脫機到磁盤,則需要採用您的方法。對於大多數目的而言,將輸出累積在RAM中是很好的。 –
我試過這個,說stdout global沒有定義。我需要導入其他東西嗎? – Danny
對不起,我一定搞砸了一些東西,但現在可以工作了。謝謝! – Danny