Quel est l'équivalent des backticks trouvés dans Ruby et Perl en Python? C'est-à-dire, dans Ruby je peux le faire:
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 en sortie standard et me renvoie le code d'erreur de cette opération.
output = os.popen('cat /tmp/baz').read()
Le moyen le plus flexible est d'utiliser le module subprocess
:
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 versions plus anciennes, la fonction spéciale check_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 à granularité fine:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
Toutes ces fonctions prennent en charge paramètres de mots clés pour personnaliser la façon dont le sous-processus est exécuté. 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 limitations .
qch a raison . Vous pouvez également utiliser os.popen (), mais lorsqu'il est disponible (Python 2.4+), le sous-processus est généralement préférable.
Cependant, contrairement à certaines langues 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 à l'intérieur de la langue. Il est plus lent, moins fiable et dépend de la plate-forme. Votre exemple serait mieux:
foo= open('/tmp/baz').read()
eta:
baz est un répertoire et j'essaie d'obtenir le contenu de tous les fichiers de ce répertoire
? cat sur un répertoire m'obtient 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 d'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 dedans, vous pouvez le placer dans une seule ligne:
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"])
A partir de Python 3.5 en avant, la manière recommandée est d'utiliser subprocess.run
. Pour obtenir le même comportement que vous décrivez, vous utiliseriez:
output = subprocess.run("ls", Shell=True, stdout=subprocess.PIPE).stdout
Cela renverra un objet bytes
. Vous voudrez peut-être ajouter .decode("ascii")
ou .decode("utf-8")
à la fin pour obtenir un str
.
Le moyen le plus simple est d'utiliser le package de commandes.
import commands
commands.getoutput("whoami")
Production:
"bganesan"
import os
foo = os.popen('cat /tmp/baz', 'r').read()
J'utilise
(6: 0) $ python --version Python 2.7.1
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, j'ai remplacé
["prog", "arg"]
avec
"prog arg"
et a obtenu le comportement d'expansion de Shell qui était souhaité (le "prog arg" de la Perl)
print subprocess.Popen ("ls -ld/tmp/v *", stdout = subprocess.PIPE, Shell = True) .communicate () [0]
J'ai arrêté d'utiliser python il y a quelque temps parce que j'étais ennuyé par la difficulté de faire l'équivalent de Perl `cmd ...`. Je suis heureux de trouver Python a rendu cela raisonnable.
Cela ne fonctionnera pas en python3, mais en python2 vous pouvez étendre str
avec une méthode __repr__
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`
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 "choisissez une valeur par défaut raisonnable".
L'opérateur backtick
(`) a été supprimé dans Python 3
. Il est similaire à une citation simple et difficile à taper sur certains claviers. Au lieu de backtick
, utilisez la fonction intégrée équivalente repr()
.