Sistemin çıktısını bir değişkene atayın ve ekranda görüntülenmesini engelleyin


305

Kullanarak çalıştırdığım bir komutun çıktısını os.systembir değişkene atamak ve ekrana çıkmasını önlemek istiyorum. Ancak, aşağıdaki kodda, çıktı ekrana gönderilir ve yazdırılan değer var0'dır, bu da komutun başarılı bir şekilde çalışıp çalışmadığını gösterir. Komut çıktısını değişkene atamanın ve ekranda görüntülenmesini durdurmanın herhangi bir yolu var mı?

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


4
Kullanmayın os.system(ne de os.popensen kabul Yanıt başına): kullanım subprocess.Popen, 's yolu daha iyi!
Alex Martelli

1
@AlexMartelli, alt süreçte karmaşık komutlar (örn. Borulu) kullanılamaz.Popen (), ancak os.system ile
vak

2
@vak, elbette boruları ve c w / kullanabilirsiniz subprocess.Popen- sadece ekleyin shell=True!
Alex Martelli

@AlexMartelli shell=True(genellikle) çok kötü bir fikir! Ne yürüttüğünüzden çok emin olmalısınız :)
Ignacio Fernández

Yanıtlar:


444

"Kimden Python Bash ters tırnakların Eşdeğer sen kullanımına isteyebilirsiniz ne uzun zaman önce sorulan," dır popen:

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

Python 3.6 için dokümanlardan ,

Bu, alt işlem kullanılarak gerçekleştirilir. alt süreçleri yönetmenin ve onlarla iletişim kurmanın daha güçlü yolları için sınıfın belgelerine bakın.


İşte ilgili kod subprocess:

import subprocess

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

6
Walter'ın subprocess.check_outputçözümünün, umursamadığınız sürece aradığınız Pythonic tek astarına daha yakın olduğunu unutmayın stderr.
chbrown

11
@ChrisBunch Suprocess neden daha iyi bir çözümdür os.popen?
Martin Thoma

6
Asla kullanmamalısın shell=True. Bkz. Docs.python.org/3/library/…
dylnmc

44
Ben bu rastlamak devam ve merak her zaman - neden açık kod bir satır yerine üç karmaşık kod satır daha iyidir?
Ant6n

3
Sadece (neredeyse) asla kullanmamalısınız shell=True, aynı zamanda bu durumda da yanlıştır. shell=Trueyapar kabuk yerine çocuk sürecini catböylece, outve errstdout'unu / stderr olan kabuk ziyade sürecin catsüreç
villapx

180

Ayrıca subprocess, Python popentipi çağrıların tüm ailesinin yerini almak için yapılmış olan modüle bakmak da isteyebilirsiniz .

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

Sahip olduğu avantaj, standart giriş / çıkış / hata akışlarının bağlı olduğu komutları nasıl çağıracağınız konusunda bir ton esneklik olmasıdır.


2
not, check_outputpython 2.7 ile eklendi docs.python.org/2.7/library/…
phyatt

1
stderr=subprocess.STDOUTStandart hataları da yakalamak için ekleyin
Dolan Antenucci

47

Komutlar modülü bunu yapmanın oldukça üst düzey bir yoludur:

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

durumu 0, çıktı / etc / services içeriğidir.


43
Komutlar modülünün belgelerinden alıntı : "2.6 sürümünden bu yana kullanımdan kaldırıldı: Komutlar modülü Python 3'te kaldırıldı. Bunun yerine alt işlem modülünü kullanın." .
Cristian Ciupitu

4
emin eski ama bazen sadece birkaç satır kod hızlı ve kolay bir şey yapmak istiyorum.
anon58192932

5
@advocate, alt işlemin check_output komutuna bakın. Hızlı, kolay ve yakında amortismana tabi tutulmayacak!
Luke Stanley

29

Python 3.5+ için alt işlem modülünden çalıştırma işlevini kullanmanız önerilir . Bu CompletedProcess, çıktıyı ve dönüş kodunu kolayca elde edebileceğiniz bir nesne döndürür . Yalnızca çıktıyla ilgilendiğiniz için böyle bir yardımcı program yazabilirsiniz.

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

Unutmayın run () için "capture_output = True" seçeneği
Elysiumplain

24

Bunun zaten yanıtlandığını biliyorum, ancak Popen'i from x import xve işlevlerini kullanarak aramak için potansiyel olarak daha iyi görünümlü bir yolu paylaşmak istedim :

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 yıl sonra, bu benim için işe yaradı. Bunu denilen ayrı bir dosyaya attım cmd.pyve sonra ana dosyama yazdım from cmd import cmdlineve gerektiği gibi kullandım.
Ücretler KA

1
0 döndüren os.system ile aynı sorunu alıyordum, ama bu yöntemi denedim ve harika çalışıyor! Ve bir bonus olarak güzel ve düzenli görünüyor :) Teşekkürler!
Sophie Muspratt

4

Ben os.system geçici dosyası ile yapmak:

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 ve 3, özellikle stdout ve stderr için PIPE kullanmaktan kaçınmayı söylüyor.

Doğru yol

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.