Pythonのforループでのexecの使用

私はコマンドの出力の各行を通過するforループを実行しようとしています。例:

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

システムにインストールされているビデオカードの量を試してみる。しかし、forループの行に構文を書いているようには見えません。

私はexec用のライブラリをインポートする必要がありますか?または私はそれを間違って使用していますか?または両方?

ありがとう

3

4 答え

exec executes Python code, not an external command. You're looking for 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)
6
追加された
私はこれを試して、stdoutグローバルは定義されていないと言います。私は何か他のものを輸入しなければなりませんか?
追加された 著者 Danny,
申し訳ありませんが、私は何かを台無しにしているに違いないが、今働いています。ありがとう!
追加された 著者 Danny,

キーワード exec は、 Pythonコードそれは新しいプロセスを開始しません。

代わりに、サブプロセスモジュールをお試しください。

lines = subprocess.check_output(["lspci"]).split('\n')
count = sum('VGA' in line for line in lines)
5
追加された
これはうまくいきましたが、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 <�​​/ code>を使うと、1回の撮影で行数を取得できます。

import os
count = os.popen('lspci | grep VGA | wc -l').read()
0
追加された
サブプロセスモジュールが置き換えられましたos.popen
追加された 著者 Corey Goldberg,

私はこの種の目的のためにpythonでこのユーティリティ関数を書いた

(一時ファイルを使用する理由は、サブプロセスを開いてsubprocess.PIPEを使用してstdoutを取得した場合、stdoutが64kを超えるデータになると、Pythonはちょうどハングします)。

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
追加された
パイプから出力を読み込む前に p.wait()呼び出すので、あなたのプログラム(Pythonを非難することはできません)はハングします。あなたのOSパイプバッファサイズは明らかに64kなので、プログラムはすべての出力を書き込む前に決して終了しません。代わりに、 p.wait()を呼び出す前にパイプ出力を読み込み、一時ファイルをまったく使用しないで 読むことができます。または、 subprocess.communicate のようなものを使用することもできます> を参照してください。
追加された 著者 Greg Hewgill,
非常に大量の出力(数百メガバイトのようなRAMに合理的に収まるもの以上)を期待し、ディスクにスプールしたい場合は、あなたのアプローチが必要です。ほとんどの場合、出力をRAMに蓄積するのは問題ありません。
追加された 著者 Greg Hewgill,
Pythonのバグではなく、これがピップバッファサイズの問題であると合意しました。しかし、私はtempfileの回避策が今のところ好きです。あなたはそれがパイプから文字列を読み込んで追加するか、またはコミュニケーションを使うことに比べて、何らかの短所があると思いますか?
追加された 著者 uncreative,