Frage

Was ist das Äquivalent der Backticks in Ruby und Perl in Python gefunden? Das heißt, in Ruby Ich kann dies tun:

foo = `cat /tmp/baz`

Was ist die äquivalente Aussage aussehen wie in Python? Ich habe versucht, os.system("cat /tmp/baz") aber das bringt das Ergebnis auf Standard aus und kehrt zu mir den Fehlercode dieser Operation.

War es hilfreich?

Lösung

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

Andere Tipps

Die flexibelste Art und Weise zu benutzen ist die subprocess Modul:

import subprocess

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

capture_output in Python 3.7 kann die Sonderfunktion check_output() für ältere Versionen eingeführt wurde stattdessen verwendet werden:

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

Sie können auch manuell ein subprocess Objekt konstruieren, wenn Sie feinkörnige Kontrolle müssen:

proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()

Alle diese Funktionen unterstützen Stichwort Parameter anpassen, wie genau die subprocess ausgeführt. Sie können zum Beispiel shell=True verwenden das Programm durch den Shell ausführen, wenn Sie Dinge wie Dateinamen-Erweiterungen von * brauchen, aber das kommt mit Einschränkungen .

etw ist richtig . Sie können auch verwenden os.popen (), aber wo verfügbar (Python 2.4 +) subprocess ist in der Regel vorzuziehen.

Im Gegensatz zu einigen Sprachen, die es fördern, ist es im Allgemeinen schlechte Form betrachtet einen Teilprozess, um zu laichen, wo Sie die gleiche Arbeit in der Sprache zu tun. Es ist langsamer, weniger zuverlässig und plattformabhängig. Ihr Beispiel wäre besser dran, wie:

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

eta:

  

baz ist ein Verzeichnis, und ich versuche, den Inhalt aller Dateien in diesem Verzeichnis zu erhalten

? Katze auf einem Verzeichnis wird mir einen Fehler.

Wenn Sie eine Liste von Dateien:

import os
foo= os.listdir('/tmp/baz')

Wenn Sie den Inhalt aller Dateien in einem Verzeichnis wollen, so etwas wie:

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)

oder, wenn Sie sicher sein können, gibt es keine Verzeichnisse dort, können Sie es in einem Einzeiler passen könnte:

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

Von Python 3.5 weiter, ist der empfohlene Weg subprocess.run . Um das gleiche Verhalten wie Sie beschreiben, würden Sie verwenden:

output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout

Dies wird ein bytes Objekt zurück. Sie könnten .decode("ascii") oder .decode("utf-8") an das Ende anhängen wollen eine str zu erhalten.

Der einfachste Weg ist, Befehle Paket zu verwenden.

import commands

commands.getoutput("whoami")

Ausgabe:

  

'bganesan'

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

Ich bin mit

  

(6: 0) $ python --version   Python 2.7.1

Eines der Beispiele oben ist:

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

Für mich ist fehlgeschlagen dies das Verzeichnis / tmp zuzugreifen. Nach einem Blick auf dem doc-String für subprocess ersetzt I

  

[ "prog", "arg"]

mit

  

"prog arg"

und bekam das Shell-Ausdehnungsverhalten, die gewünscht wurde (a la Perl `prog arg`)

  

Druck subprocess.Popen ( "ls ld / tmp / v *", stdout = subprocess.PIPE, shell = True) .Kommunizieren () [0]


Ich höre auf Python ein mit Weile zurück, weil ich war verärgert über die Schwierigkeit des Äquivalents von Perl `cmd ...` tun. Ich bin froh, Python zu finden hat diese vernünftig gemacht.

Wenn Sie subprocess.Popen verwenden, denken Sie daran bufsize angeben. Der Standardwert ist 0, was bedeutet, „unbuffered“, nicht „einen angemessenen Standard wählen“.

Dies wird nicht in python3 arbeiten, aber in python2 können Sie str mit einer benutzerdefinierten __repr__ Methode erweitern, die Shell-Befehl aufruft und gibt es etwa so:

#!/usr/bin/env python

import os

class Command(str):
    """Call system commands"""

    def __repr__(cmd):
        return os.popen(cmd).read()

Welche Sie können wie Sie mit

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

Die backtick ( `) Operator wurde entfernt in Python 3. Es ist zum Verwechseln ähnlich einen Apostroph, und hart, einige Tastaturen tippen auf. Anstelle der backtick, verwenden, um die äquivalente integrierte Funktion repr() .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top