Quel est l'équivalent des backticks trouvés dans Ruby et Perl en Python? Autrement dit, dans Ruby, je peux faire ceci:
foo = `cat /tmp/baz`
À quoi ressemble la déclaration équivalente en Python? J'ai essayé os.system("cat /tmp/baz")
mais cela met le résultat à la norme et me renvoie le code d'erreur de cette opération.
Réponses:
output = os.popen('cat /tmp/baz').read()
la source
`...`
(capturer stdout, passer stderr through) - à une exception près: Ruby permet de déterminer le code de sortie du processus$?
après coup; en Python, d'après ce que je peux dire, vous devrez utiliser lessubprocess
fonctions du module pour cela.La manière la plus flexible est d'utiliser le
subprocess
module:import subprocess out = subprocess.run(["cat", "/tmp/baz"], capture_output=True) print("program output:", out)
capture_output
a été introduit dans Python 3.7, pour les anciennes versions, la fonction spécialecheck_output()
peut être utilisée à la place:out = subprocess.check_output(["cat", "/tmp/baz"])
Vous pouvez également créer manuellement un objet de sous-processus si vous avez besoin d'un contrôle précis:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE) (out, err) = proc.communicate()
Toutes ces fonctions prennent en charge les paramètres de mots-clés pour personnaliser la façon dont le sous-processus est exécuté exactement. Vous pouvez par exemple utiliser
shell=True
pour exécuter le programme via le shell, si vous avez besoin de choses comme des extensions de nom de fichier de*
, mais cela vient avec des limitations .la source
subprocess.run()
(je ne sais pas si cela est mérité) si vous n'avez pas besoin de prendre en charge les versions antérieures ou si vous n'avez pas besoin de la flexibilité fournie parPopen()
.qc a raison . Vous pouvez également utiliser os.popen (), mais le sous-processus disponible (Python 2.4+) est généralement préférable.
Cependant, contrairement à certains langages qui l'encouragent, il est généralement considéré comme une mauvaise forme de générer un sous-processus où vous pouvez faire le même travail dans le langage. C'est plus lent, moins fiable et dépendant de la plate-forme. Votre exemple serait mieux car:
foo= open('/tmp/baz').read()
eta:
? chat sur un répertoire me donne une erreur.
Si vous voulez une liste de fichiers:
import os foo= os.listdir('/tmp/baz')
Si vous voulez le contenu de tous les fichiers dans un répertoire, quelque chose comme:
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)
ou, si vous pouvez être sûr qu'il n'y a pas de répertoires là-dedans, vous pouvez l'inclure dans une seule ligne:
path= '/tmp/baz' foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
la source
foo = subprocess.check_output(["cat", "/tmp/baz"])
la source
À partir de Python 3.5, la méthode recommandée est d'utiliser
subprocess.run
. Depuis Python 3.7, pour obtenir le même comportement que celui que vous décrivez, vous utiliseriez:cpe = subprocess.run("ls", shell=True, capture_output=True)
Cela renverra un
subprocess.CompletedProcess
objet. La sortie vers stdout sera danscpe.stdout
, la sortie vers stderr sera danscpe.stderr
, qui seront tous les deux desbytes
objets. Vous pouvez décoder la sortie pour obtenir unstr
objet en utilisantcpe.stdout.decode()
ou obtenir un en passanttext=True
àsubprocess.run
:cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)
Dans ce dernier cas,
cpe.stdout
etcpe.stderr
sont tous deux desstr
objets.la source
text=True
paramètre pour récupérer une chaîne au lieu d'octets.Le moyen le plus simple est d'utiliser le package de commandes.
import commands commands.getoutput("whoami")
Production:
la source
import os foo = os.popen('cat /tmp/baz', 'r').read()
la source
j'utilise
L'un des exemples ci-dessus est:
import subprocess proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() print "program output:", out
Pour moi, cela n'a pas réussi à accéder au répertoire / tmp. Après avoir regardé la chaîne doc pour le sous-processus que j'ai remplacé
avec
et a obtenu le comportement d'extension du shell souhaité (à la Perl's `prog arg`)
J'ai arrêté d'utiliser python il y a quelque temps car j'étais ennuyé par la difficulté de faire l'équivalent de perl `cmd ...`. Je suis heureux de constater que Python a rendu cela raisonnable.
la source
Si vous utilisez subprocess.Popen, n'oubliez pas de spécifier bufsize. La valeur par défaut est 0, ce qui signifie «sans tampon», et non «choisir une valeur par défaut raisonnable».
la source
Cela ne fonctionnera pas en python3, mais en python2, vous pouvez étendre
str
avec une__repr__
méthode personnalisée qui appelle votre commande shell et la renvoie comme suit:#!/usr/bin/env python import os class Command(str): """Call system commands""" def __repr__(cmd): return os.popen(cmd).read()
Que vous pouvez utiliser comme
#!/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`
la source
repr()
L'
backtick
opérateur (`) a été supprimé dansPython 3
. Il est confusément similaire à un guillemet simple et difficile à taper sur certains claviers. Au lieu debacktick
, utilisez la fonction intégrée équivalenterepr()
.la source