1. ホーム
  2. python

[解決済み] サブプロセスの標準出力を変数にパイプする[重複]。

2022-10-28 16:27:48

質問

でコマンドを実行したい。 pythong で、サブプロセスモジュールを使ってコマンドを実行し、その出力を変数に格納したい。しかし、コマンドの出力をターミナルに出力させたくありません。 このコードに対して

def storels():
   a = subprocess.Popen("ls",shell=True)
storels()

ディレクトリの一覧をターミナルで取得するのですが、その際に、ディレクトリの一覧を保存するのではなく a . も試しました。

 def storels():
       subprocess.Popen("ls > tmp",shell=True)
       a = open("./tmp")
       [Rest of Code]
 storels()

これはまた、私のターミナルにlsの出力を表示します。私はこのコマンドをやや古い os.system メソッドで試したこともあります。 ls > tmp をターミナルで実行しても ls をターミナルに出力せず、それを tmp . しかし、同じことが起こります。

編集してください。

marcogさんのアドバイスに従ったところ、より複雑なコマンドを実行したときだけ、以下のエラーが発生しました。 cdrecord --help . Pythonはこれを吐き出します。

Traceback (most recent call last):
  File "./install.py", line 52, in <module>
    burntrack2("hi")
  File "./install.py", line 46, in burntrack2
    a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

どのように解決するのですか?

の出力を得るには ls の出力を得るには、次のようにします。 stdout=subprocess.PIPE .

>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo

コマンドは cdrecord --help は標準エラー出力をするので、代わりにそれをパイプする必要があります。また、以下のようにコマンドをトークンのリストに分割する必要がありますし、別の方法として shell=True を渡すこともできますが、これは本格的なシェルを起動するので、コマンド文字列の内容を制御していない場合は危険な場合があります。

>>> proc = subprocess.Popen(['cdrecord', '--help'], stderr=subprocess.PIPE)
>>> output = proc.stderr.read()
>>> print output
Usage: wodim [options] track1...trackn
Options:
    -version    print version information and exit
    dev=target  SCSI target to use as CD/DVD-Recorder
    gracetime=# set the grace time before starting to write to #.
...

stdoutとstderrの両方に出力するコマンドがあり、それらをマージしたい場合、stderrをstdoutにパイプし、stdoutをキャッチすることによってそれを行うことができます。

subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

で述べたように クリス・モーガン を使用する必要があります。 proc.communicate() の代わりに proc.read() .

>>> proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out, err = proc.communicate()
>>> print 'stdout:', out
stdout: 
>>> print 'stderr:', err
stderr:Usage: wodim [options] track1...trackn
Options:
    -version    print version information and exit
    dev=target  SCSI target to use as CD/DVD-Recorder
    gracetime=# set the grace time before starting to write to #.
...