web-dev-qa-db-ja.com

PythonのBash Backticksと同等

RubyおよびPythonのPerlにあるバックティックに相当するものは何ですか?つまり、Rubyでこれを行うことができます。

_foo = `cat /tmp/baz`
_

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

77
Chris Bunch
output = os.popen('cat /tmp/baz').read()
90
John Kugelman

最も柔軟な方法は、 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_のファイル名展開のようなものが必要な場合は、たとえば_*_を使用してシェルを介してプログラムを実行できますが、これには limitations が付属します。

81
sth

sthが正しい 。 os.popen()を使用することもできますが、可能であれば(Python 2.4以降)サブプロセスが一般的に推奨されます。

ただし、それを促進する一部の言語とは異なり、言語内で同じジョブを実行できるサブプロセスを生成することは一般に悪い形式と見なされます。遅く、信頼性が低く、プラットフォームに依存します。あなたの例は次のように良いでしょう:

foo= open('/tmp/baz').read()

イータ:

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)

または、そこにディレクトリがないことを確認できる場合は、1行に収めることができます。

path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
26
bobince
foo = subprocess.check_output(["cat", "/tmp/baz"])
15
jfs

Python 3.5以降、推奨される方法は _subprocess.run_ を使用することです。説明と同じ動作を得るには、次を使用します。

_output = subprocess.run("ls", Shell=True, stdout=subprocess.PIPE).stdout
_

これはbytesオブジェクトを返します。 strを取得するには、.decode("ascii")または.decode("utf-8")を末尾に追加することをお勧めします。

9
gerrit

最も簡単な方法は、コマンドパッケージを使用することです。

import commands

commands.getoutput("whoami")

出力:

「bganesan」

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

私は使っています

(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"]

「プログラム引数」

望まれるシェル拡張動作を取得しました(Perlの `prog arg`に類似)

print subprocess.Popen( "ls -ld/tmp/v *"、stdout = subprocess.PIPE、Shell = True).communicate()[0]


Perlの `cmd ...`に相当することの難しさに悩まされたので、しばらく前にpythonを使用するのをやめました。Pythonはこれを合理的なものにしました。

2
funkyj

これはpython3では機能しませんが、python2では、シェルコマンドを呼び出して次のように返すカスタム__repr__メソッドでstrを拡張できます。

#!/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`
1
ThorSummoner

Subprocess.Popenを使用する場合は、bufsizeを指定することを忘れないでください。デフォルトは0で、これは「妥当なデフォルトを選択する」のではなく、「バッファなし」を意味します。

1
George

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

0
Pedro Lobito