os.systemの出力を変数に割り当て、画面に表示されないようにします


305

実行しos.systemているコマンドの出力を変数に割り当てて、画面に出力されないようにしたい。しかし、以下のコードでは、出力は画面に送信され、出力される値varは0です。これは、コマンドが正常に実行されたかどうかを示していると思います。コマンド出力を変数に割り当てて、画面に表示されないようにする方法はありますか?

var = os.system("cat /etc/services")
print var #Prints 0

2
可能性のある重複Pythonでバッククォートの等価
MSW

4
使用しないでくださいos.system(もos.popen、あなたが受け入れ答えにつき、):使用subprocess.Popen、それの方法より良いです!
Alex Martelli、2010

1
@ AlexMartelli、subprocess.Popen()で複雑なコマンド(パイプなど)を使用することはできませんが、os.systemで使用できます
vak

2
@vak、もちろんパイプ&c w /を使用できますsubprocess.Popen-追加するだけshell=Trueです!
Alex Martelli、2015年

@AlexMartelli shell=Trueは(一般的に)非常に悪い考えです!あなたは何を実行しているのかを非常に確信している必要があります:)
IgnacioFernández16年

回答:


444

かなり前に私が尋ねた「PythonでのBashバックティックの同等物」から、あなたが使いたいと思うものはpopen次のとおりです:

os.popen('cat /etc/services').read()

Python 3.6ドキュメントから、

これはsubprocess.Popenを使用して実装されます。サブプロセスを管理および通信するためのより強力な方法については、そのクラスのドキュメントを参照してください。


これに対応するコードはsubprocess次のとおりです。

import subprocess

proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

6
Walterのsubprocess.check_outputソリューションは、気にしない限り、探しているように見えるPythonicワンライナーに近いことに注意してくださいstderr
chbrown、

11
@ChrisBunchなぜsuprocessの方が優れたソリューションなのですos.popenか?
Martin Thoma 14年

6
(ほとんど)は使用しないでくださいshell=Truedocs.python.org/3/library/…を
dylnmc

44
私はこれに遭遇し続け、いつも疑問に思っています-明白なコードの1行ではなく、なぜ3行の複雑なコードがある方が良いのですか?
Ant6n

3
(ほとんど)を使用すべきでないだけでなくshell=True、この場合も正しくありません。shell=True作るシェルの子プロセスをよりむしろcat、そうouterrの標準出力/標準エラー出力されているシェルのプロセスではなく、のcatプロセス
villapx

180

またsubprocess、Python popenタイプの呼び出しのファミリ全体を置き換えるために作成されたモジュールを確認することもできます。

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)

これの利点は、コマンドの呼び出し方法、標準の入出力ストリーム、エラーストリームが接続されている場所など、さまざまな柔軟性があることです。


2
メモ、check_outputpython 2.7docs.python.org/2.7/library/…で
phyatt

1
stderr=subprocess.STDOUT標準エラーをキャプチャするために追加する
Dolan Antenucci

47

コマンドモジュールは、これを行うためのかなり高レベルな方法です。

import commands
status, output = commands.getstatusoutput("cat /etc/services")

ステータスは0、出力は/ etc / servicesの内容です。


43
コマンドモジュールのドキュメントからの引用:「バージョン2.6で廃止:コマンドモジュールはPython 3で削除されました。代わりにサブプロセスモジュールを使用してください。」
クリスティアンCiupitu 2013

4
古くなっていることを確認してください。数行のコードですばやく簡単に何かを実行したい場合もあります。
anon58192932

5
@advocateはサブプロセスのcheck_outputコマンドをチェックアウトします。すばやく簡単に、すぐに減価することはありません。
ルークスタンリー

29

Python 3.5以降では、サブプロセスモジュールのrun関数を使用することをお勧めします。これはCompletedProcessオブジェクトを返し、そこから出力と戻りコードを簡単に取得できます。出力のみに関心があるので、このようなユーティリティラッパーを作成できます。

from subprocess import PIPE, run

def out(command):
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
    return result.stdout

my_output = out("echo hello world")
# Or
my_output = out(["echo", "hello world"])

run()の「capture_output = True」オプションを忘れないでください
Elysiumplain

24

私はこれがすでに回答されていることを知っていますが、from x import xおよび関数の使用を介してPopenを呼び出すための見栄えが良い方法を共有したいと思います。

from subprocess import PIPE, Popen


def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    )
    return process.communicate()[0]

print cmdline("cat /etc/services")
print cmdline('ls')
print cmdline('rpm -qa | grep "php"')
print cmdline('nslookup google.com')

1
3年後、これは私のために働いたものです。これをと呼ばれる別のファイルcmd.pyに入れてから、メインファイルに書き込んfrom cmd import cmdlineで、必要に応じて使用しました。
運賃KA

1
os.systemが0を返すことで同じ問題が発生していましたが、この方法を試しましたが、うまく機能します!そしてボーナスとして、それは見栄えがよく、きれいに見えます:)ありがとう!
ソフィー・マスプラット

4

私はそれをos.system一時ファイルで行います:

import tempfile,os
def readcmd(cmd):
    ftmp = tempfile.NamedTemporaryFile(suffix='.out', prefix='tmp', delete=False)
    fpath = ftmp.name
    if os.name=="nt":
        fpath = fpath.replace("/","\\") # forwin
    ftmp.close()
    os.system(cmd + " > " + fpath)
    data = ""
    with open(fpath, 'r') as file:
        data = file.read()
        file.close()
    os.remove(fpath)
    return data

1

Python 2.6と3は、stdoutとstderrにPIPEを使用しないことを明確に述べています。

正しい方法は

import subprocess

# must create a file object to store the output. Here we are getting
# the ssid we are connected to
outfile = open('/tmp/ssid', 'w');
status = subprocess.Popen(["iwgetid"], bufsize=0, stdout=outfile)
outfile.close()

# now operate on the file
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.