2011-10-27 54 views
3

我試圖運行一個for循環,它遍歷命令輸出的每一行。例如:在python中使用exec for循環

for line in exec 'lspci | grep VGA': 
    count = count + 1 

嘗試獲取安裝在系統中的視頻卡數量。但是它似乎沒有在for循環行上排列語法。

我必須爲exec導入一個庫嗎?還是我用它錯了?或兩者?

由於

回答

6

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) 
+0

我試過這個,說stdout global沒有定義。我需要導入其他東西嗎? – Danny

+0

對不起,我一定搞砸了一些東西,但現在可以工作了。謝謝! – Danny

5

關鍵字exec執行Python代碼。它不啓動新的進程。

嘗試使用subprocess模塊。

lines = subprocess.check_output(["lspci"]).split('\n') 
count = sum('VGA' in line for line in lines) 
+0

這可能會起作用,但RHEL5.5似乎隨2.4.3一起發佈,我無法輕鬆升級所有需要部署的系統。雖然 – Danny

0

你想用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() 
+1

子進程模塊替換os.popen –

0

我在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 
+0

你的程序(你不能責怪Python)因爲你在從管道讀取任何輸出之前調用'p.wait()'*。您的OS管道緩衝區大小顯然爲64k,因此在寫入其所有輸出之前,程序永遠不會完成。相反,你可以在調用'p.wait()'之前讀取管道輸出*,避免使用臨時文件。或者,您可以使用['subprocess.communicate'](http://docs.python.org/library/subprocess.html#subprocess.Popen。溝通),爲您處理所有這些。 –

+0

同意這是一個點緩衝區大小問題 - 而不是一個python的bug。但我現在喜歡臨時文件解決方法。你認爲它與閱讀和附加管道中的字符串或使用通信有什麼不利嗎? – uncreative

+0

如果您期望*非常*大量的輸出(超過可以合理安裝在RAM中的數量,比如數百兆字節)並且想要將其假脫機到磁盤,則需要採用您的方法。對於大多數目的而言,將輸出累積在RAM中是很好的。 –