PythonのRubyとPerlにあるバックティックに相当するものは何ですか?つまり、Rubyでは次のことができます。
foo = `cat /tmp/baz`
Pythonでの同等のステートメントはどのように見えますか?私は試しましos.system("cat /tmp/baz")
たが、結果が標準出力になり、その操作のエラーコードが返されます。
回答:
output = os.popen('cat /tmp/baz').read()
`...`
素晴らしく簡潔で、実際にRubyと同等(stdoutのキャプチャ、stderrのパススルー)-1つの例外を除きます。Rubyでは、事後にプロセスの終了コードを判別できます$?
。Pythonでは、私が言えることからsubprocess
、そのためにモジュールの関数を使用する必要があります。
最も柔軟な方法は、subprocess
モジュールを使用することです。
import subprocess
out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)
capture_output
Python 3.7で導入されました。古いバージョンでは、check_output()
代わりに特別な関数を使用できます。
out = subprocess.check_output(["cat", "/tmp/baz"])
きめ細かい制御が必要な場合は、サブプロセスオブジェクトを手動で作成することもできます。
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
これらの関数はすべて、サブプロセスの実行方法を正確にカスタマイズするためのキーワードパラメータをサポートしています。たとえばshell=True
、のファイル名展開などが必要な場合は、シェルを介してプログラムを実行するために使用できますが*
、それには制限があります。
subprocess.run()
(それに値するかどうかはわかりません)Popen()
。
sthは正しいです。os.popen()を使用することもできますが、利用可能な場合(Python 2.4以降)のサブプロセスが一般的に推奨されます。
ただし、それを推奨する一部の言語とは異なり、言語内で同じジョブを実行できるサブプロセスを生成することは、一般的に悪い形式と見なされます。速度が遅く、信頼性が低く、プラットフォームに依存します。あなたの例は次のようにしたほうがよいでしょう:
foo= open('/tmp/baz').read()
eta:
bazはディレクトリであり、そのディレクトリ内のすべてのファイルの内容を取得しようとしています
?ディレクトリ上の猫は私にエラーを取得します。
ファイルのリストが必要な場合:
import os
foo= os.listdir('/tmp/baz')
ディレクトリ内のすべてのファイルの内容が必要な場合は、次のようになります。
contents= []
for leaf in os.listdir('/tmp/baz'):
path= os.path.join('/tmp/baz', leaf)
if os.path.isfile(path):
contents.append(open(path, 'rb').read())
foo= ''.join(contents)
または、そこにディレクトリがないことを確認できる場合は、それをワンライナーに収めることができます。
path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
Python 3.5以降では、を使用することをお勧めしますsubprocess.run
。Python 3.7以降、説明したのと同じ動作を得るには、次を使用します。
cpe = subprocess.run("ls", shell=True, capture_output=True)
これにより、subprocess.CompletedProcess
オブジェクトが返されます。stdoutへの出力はになり、cpe.stdout
stderrへの出力はにcpe.stderr
なりbytes
ます。どちらもオブジェクトになります。str
を使用して出力をデコードし、オブジェクトを取得するcpe.stdout.decode()
か、:に渡すtext=True
ことでを取得できますsubprocess.run
。
cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)
後者の場合、cpe.stdout
とcpe.stderr
は両方ともstr
オブジェクトです。
text=True
パラメーターを使用してバイトの代わりにstrを取得できます。
最も簡単な方法は、コマンドパッケージを使用することです。
import commands
commands.getoutput("whoami")
出力:
「bganesan」
import os
foo = os.popen('cat /tmp/baz', 'r').read()
使っています
(6:0)$ python --version Python 2.7.1
上記の例の1つは次のとおりです。
import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out
私にとって、これはディレクトリ/ tmpへのアクセスに失敗しました。サブプロセスのドキュメント文字列を確認した後、置き換えました
["prog"、 "arg"]
と
「progarg」
必要なシェル拡張動作を取得しました(Perlの `prog arg`)
print subprocess.Popen( "ls -ld / tmp / v *"、stdout = subprocess.PIPE、shell = True).communicate()[0]
perl `cmd ...`と同等のことをするのが難しいことに悩まされたので、しばらく前にpythonの使用をやめました。Pythonがこれを合理的にしているのを見つけてうれしいです。
これはpython3では機能しませんが、python2では、シェルコマンドを呼び出して次のように返すstr
カスタム__repr__
メソッドで拡張できます。
#!/usr/bin/env python
import os
class Command(str):
"""Call system commands"""
def __repr__(cmd):
return os.popen(cmd).read()
あなたが好きに使うことができるもの
#!/usr/bin/env python
from command import Command
who_i_am = `Command('whoami')`
# Or predeclare your shell command strings
whoami = Command('whoami')
who_i_am = `whoami`