2011-02-11 17 views
64

私は、コマンドラインで何:Python:Subprocessで出力をリダイレクトする方法

import subprocess, shlex 
my_cmd = 'cat file1 file2 file3 > myfile' 
args = shlex.split(my_cmd) 
subprocess.call(args) # spits the output in the window i call my python program 
+0

サブプロセスでこのようなコマンドを実行しても、出力が得られません。 _cat file1 file2 file3_の出力をpythonにリダイレクトする_> myfile_なしで実行したいのですか? – PoltoS

+0

@PoltoSいくつかのファイルに参加し、結果ファイルを処理したいとします。私はcatを使うのが最も簡単な方法だと思った。それを行うためのより良い/ pythonの方法はありますか? – catatemypythoncode

+0

'os.sendfile()'ベースの解決策が可能です、[Pythonでunix catコマンドを再現する]を参照してください(http://stackoverflow.com/q/11532980/4279) – jfs

答えて

23

UPDATE:os.systemは、Python 3で利用できるまだいえ、推奨され

私は、Pythonで何をしたいか

cat file1 file2 file3 > myfile 


使用os.system

os.system(my_cmd) 
完全

p = subprocess.Popen(my_cmd, shell=True) 
os.waitpid(p.pid, 0) 

OTOH、あなたがシステムを回避することができます呼び出し:

あなたが本当にサブプロセスを使用したい場合は、ここでは(主にサブプロセスのドキュメントから持ち上げ)ソリューションです

import shutil 

with open('myfile', 'w') as outfile: 
    for infile in ('file1', 'file2', 'file3'): 
     shutil.copyfileobj(open(infile), outfile) 
+1

それはうまくいきますが、私に聞いてみましょう:os.systemがすでに仕事を終えている場合、サブプロセスライブラリのポイントは何ですか?今度は自分自身でこれをやっているので、今度はos.systemを使ってうまくいくでしょうが、この作業に専念するライブラリなので、サブプロセスを使用していたはずです。 – catatemypythoncode

+0

サブプロセスライブラリは 'os.system'よりはるかに柔軟性があり、' os.system'を正確にモデル化できますが、作業するのがより複雑です。 –

+11

'os.system'は' subprocess'の前に来ました。前者は後者が置き換えようとする旧来のAPIです。 – Santa

4

@ Polo私はいくつかのファイルに参加して、その結果のファイルを処理したいです。私はcatを使うのが最も簡単な方法だと思った。それを行うためのより良い/ pythonの方法はありますか?

もちろん

with open('myfile', 'w') as outfile: 
    for infilename in ['file1', 'file2', 'file3']: 
     with open(infilename) as infile: 
      outfile.write(infile.read()) 
165

だけsubprocess.callstdout引数のためのオープンファイルハンドルを渡し、出力をリダイレクトするために、あなたの元の質問に答えるために:

# Use a list of args instead of a string 
input_files = ['file1', 'file2', 'file3'] 
my_cmd = ['cat'] + input_files 
with open('myfile', "w") as outfile: 
    subprocess.call(my_cmd, stdout=outfile) 

しかし、他の人が持っているようにこの目的のためにcatのような外部コマンドを使用することは全く無関係であることが指摘されています。

+2

これは、Pythonのシェルを使用するときの配管に関する一般的な質問の答えになります。 –

+25

これは正解とマークされたものではなく、正解です。 –

+0

これは正解、最善のアプローチです。 –

0

1つの興味深いケースは、類似のファイルを追加してファイルを更新することです。その後、プロセスで新しいファイルを作成する必要はありません。大きなファイルを追加する必要がある場合に特に便利です。 Pythonから直接teminalコマンドラインを使用する可能性があります。

import subprocess32 as sub 

with open("A.csv","a") as f: 
    f.flush() 
    sub.Popen(["cat","temp.csv"],stdout=f) 
0
size = 'ffprobe -v error -show_entries format=size -of default=noprint_wrappers=1:nokey=1 dump.mp4 > file' 
proc = subprocess.Popen(shlex.split(size), shell=True) 
time.sleep(1) 
proc.terminate() #proc.kill() modify it by a suggestion 
size = "" 
with open('file', 'r') as infile: 
    for line in infile.readlines(): 
     size += line.strip() 

print(size) 
os.remove('file') 

あなたはサブプロセスを使用すると、プロセスはkilled.Thisでなければなりませんが、あなたがプロセスを強制終了していない、ファイルが空になりexample.Ifであり、あなたがnothing.Itを読むことができますWindowsで実行できます。Unix上で実行できるかどうかは確認できません。

+0

これは悪いコードの例です(Unix上では動作しません; .readlines(): '、' s + = ')や' proc.kill() 'の行のために、一般的に(サブプロセスが正常に終了することは許されません(Unixでは) - フラッシュされていないコンテンツは失われます)。とにかく、バッファリングに関する注釈はコメントとして適切です。 – jfs

+0

Windowsで実行するとOKです(killはWindowsで終了するため)。 Unixではproc.terminate()を使うべきでしょうか。 @ J.F. Sebastian私のコンピュータ上にUnixシステムはありません。 – wyx

+0

Windows上で 'shlex.split()'をドロップし、 'shell = True'をドロップし、'> file'をドロップし、 'open()'などをドロップし、 'stdout = PIPE'、' Timer(1、 proc.terminate).start() ';代わりに 'output = proc.communicate()[0]'を実行してください。ここに[完全な例](http://stackoverflow.com/a/27995163/4279)があります。その他のソリューション:[ハングすることなくPythonでプロセス出力を読むのを止めますか?](http://stackoverflow.com/q/4417962/4279)注:子プロセスを手動で終了する必要はありません。他の問題に対処することができます。例えば、プロセスのstdoutがttyであるにもかかわらずプロセスの動作が異なるかもしれません。 – jfs

関連する問題