PythonのBashバックティックに相当[重複]


84

PythonのRubyとPerlにあるバックティックに相当するものは何ですか?つまり、Rubyでは次のことができます。

foo = `cat /tmp/baz`

Pythonでの同等のステートメントはどのように見えますか?私は試しましos.system("cat /tmp/baz")たが、結果が標準出力になり、その操作のエラーコードが返されます。


回答:


100
output = os.popen('cat /tmp/baz').read()

4
@mckenzm質問は、外部プロセスの出力をキャプチャすることです。Python関数の出力をキャプチャすることは、まったく別の質問になります。
John Kugelman 2015年

1
`...`素晴らしく簡潔で、実際にRubyと同等(stdoutのキャプチャ、stderrのパススルー)-1つの例外を除きます。Rubyでは、事後にプロセスの終了コードを判別できます$?。Pythonでは、私が言えることからsubprocess、そのためにモジュールの関数を使用する必要があります。
mklement0

82

最も柔軟な方法は、subprocessモジュールを使用することです。

import subprocess

out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)

capture_outputPython 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、のファイル名展開などが必要な場合は、シェルを介してプログラムを実行するために使用できますが*、それには制限があります。


2
はい、これが唯一の正しい方法です。関数でラップして、execute( "command")のようなものを呼び出すことができます
Vinko Vrsalovic 2009

この場合、bazはディレクトリであり、そのディレクトリ内のすべてのファイルの内容を取得しようとしているため、これは実際には機能しません。(cat / tmp / baz / *を実行すると、ティックで機能しますが、ここで説明する方法では機能しません)
Chris Bunch

6
re:「*」は機能しません。代わりに、subprocess.Popen(["cat"、 "/ tmp / baz"]、stdout = subprocess.PIPE、shell = True)を使用してください。glob(star)展開はシェルによって処理されるため、この場合、サブプロセッシングモジュールはシェル展開を使用する必要があります(/ bin / shで提供)。
Pasi Savolainen

1
From docs.python.org/2/library/subprocess.html#popen-constructor: "(with shell = True)argsがシーケンスの場合、最初の項目はコマンド文字列を指定し、追加の項目は追加の引数として扱われますシェル自体に。」したがって、shell = Trueを使用する場合、最初の引数はおそらく文字列「cat / tmp / baz」である必要があります。または、最初の引数としてシーケンスを使用する場合は、shell = False
onlynone 2013年

1
@gerrit:非推奨ではありません。以前のバージョンをサポートする必要がない場合、またはによって提供される柔軟性が必要ない場合は、ドキュメントで推奨されています subprocess.run()(それに値するかどうかはわかりません)Popen()
jfs 2016年

27

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

1
これは質問に対する答えではありませんでしたが、ユーザーを教育するための最良の答えです。
noamtm 2010

1
質問のタイトルは「バックティックに相当するものは何ですか」です。「cat」は単なるコマンド例だと思いました。この答えは、一般的なケースでは役に立ちません。
ジェイソン

15
foo = subprocess.check_output(["cat", "/tmp/baz"])

3
これは現在最も簡単な方法です。「subprocess.check_output」は、他の「popen」の回答が与えられた後、2010年7月にリリースされたPython2.7で追加されました。
ロバートフレミング

10

Python 3.5以降では、を使用することをお勧めしますsubprocess.run。Python 3.7以降、説明したのと同じ動作を得るには、次を使用します。

cpe = subprocess.run("ls", shell=True, capture_output=True)

これにより、subprocess.CompletedProcessオブジェクトが返されます。stdoutへの出力はになり、cpe.stdoutstderrへの出力はにcpe.stderrなりbytesます。どちらもオブジェクトになります。strを使用して出力をデコードし、オブジェクトを取得するcpe.stdout.decode()か、:に渡すtext=Trueことでを取得できますsubprocess.run

cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)

後者の場合、cpe.stdoutcpe.stderrは両方ともstrオブジェクトです。


Python 3.7以降では、text=Trueパラメーターを使用してバイトの代わりにstrを取得できます。
bwv549


3
import os
foo = os.popen('cat /tmp/baz', 'r').read()

3
これはRubyのバッククォートと同等ですが、問題がディレクトリの内容を一覧表示することである場合、これはそれを行うための最良の方法ではありません。
awatts 2009

2

使っています

(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がこれを合理的にしているのを見つけてうれしいです。


1

subprocess.Popenを使用する場合は、bufsizeを指定することを忘れないでください。デフォルトは0です。これは、「適切なデフォルトを選択する」ではなく、「バッファリングされていない」ことを意味します。


1

これは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`

4
また、おそらくこれを行うべきではありません*
ThorSummoner 2015年

-1

repr()

backtick( `)演算子を除去しにおけるPython 3。紛らわしいことに一重引用符に似ており、一部のキーボードでは入力が困難です。の代わりに、backtick同等の組み込み関数を使用しますrepr()


これは、bashバックティックと同等ではありません。
gerrit
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.