Question

Quel est l’équivalent des backticks trouvés dans Ruby et Perl en Python? C'est-à-dire qu'en Ruby, je peux faire ceci:

foo = `cat /tmp/baz`

À quoi ressemble l'instruction é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.

Était-ce utile?

La solution

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

Autres conseils

La méthode la plus souple consiste à utiliser le sous-processus 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 versions antérieures, 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 affiné:

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

Toutes ces fonctions prennent en charge les paramètres de mot clé à personnaliser comment exactement 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 d'éléments tels que des extensions de nom de fichier de * , mais avec limitations .

sth 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 à certaines langues qui l’encouragent, il est généralement considéré comme une mauvaise forme de générer un sous-processus dans lequel vous pouvez effectuer le même travail dans la langue. C'est plus lent, moins fiable et dépendant de la plate-forme. Votre exemple serait mieux comme:

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

? Un chat dans un répertoire me renvoie une erreur.

Si vous souhaitez 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 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"])

À partir de Python 3.5, la méthode recommandée consiste à utiliser subprocess.run . Pour obtenir le même comportement que vous décrivez, utilisez:

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

Ceci renverra un objet octets . Vous voudrez peut-être ajouter .decode ("ascii") ou .decode ("utf-8") à la fin pour obtenir un str .

Le moyen le plus simple consiste à utiliser le paquet de commandes.

import commands

commands.getoutput("whoami")

Sortie:

  

'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 le suivant:

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 pu accéder au répertoire / tmp. Après avoir examiné la chaîne de documentation du sous-processus, j'ai remplacé

  

["prog", "arg"]

avec

  

" prog arg "

et obtenu le comportement d'expansion de shell souhaité (comme `prog argument` de 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 constater que Python a rendu cela raisonnable.

Si vous utilisez subprocess.Popen, n'oubliez pas de spécifier bufsize. La valeur par défaut est 0, ce qui signifie "non tamponnée", et non "choisissez une valeur par défaut raisonnable".

Cela ne fonctionnera pas dans python3, mais vous pouvez étendre str avec une méthode personnalisée __ repr __ qui appelle votre commande shell et le renvoie comme suit:

#!/usr/bin/env python

import os

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

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

Ce 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`

L'opérateur backtick (`) a été supprimé dans Python 3 . Il ressemble à une citation simple et est difficile à saisir sur certains claviers. Au lieu de backtick , utilisez la fonction intégrée équivalente repr () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top