web-dev-qa-db-fra.com

Transférer la sortie de la commande Shell vers un script python

Je souhaite exécuter une commande mysql et définir sa sortie comme variable dans mon script python.

Voici la commande Shell que j'essaie d'exécuter:

$ mysql my_database --html -e "select * from limbs" | ./script.py

Voici le script python:

#!/usr/bin/env python

import sys

def hello(variable):
    print variable

Comment pourrais-je accepter la variable dans le script python et lui faire imprimer le résultat?

21
David542

Vous devez lire stdin pour récupérer les données dans le script python, par exemple.

#!/usr/bin/env python

import sys

def hello(variable):
    print variable

data = sys.stdin.read()
hello(data)

Si tout ce que vous voulez faire ici est de récupérer des données d’une base de données mysql puis de les manipuler avec Python, je l’éviterais de les transférer dans le script et d’utiliser simplement le module MySQL Python pour effectuer la requête SQL.

22
Jon Cage

Si vous souhaitez que votre script se comporte comme de nombreux outils de ligne de commande unix et accepte un canal ou un nom de fichier comme premier argument, vous pouvez utiliser les éléments suivants:

#!/usr/bin/env python
import sys

# use stdin if it's full                                                        
if not sys.stdin.isatty():
    input_stream = sys.stdin

# otherwise, read the given filename                                            
else:
    try:
        input_filename = sys.argv[1]
    except IndexError:
        message = 'need filename as first argument if stdin is not full'
        raise IndexError(message)
    else:
        input_stream = open(input_filename, 'rU')

for line in input_stream:
    print line # do something useful with each line
18
mstringer

Lorsque vous dirigez la sortie d'une commande vers un script python, il passe à sys.stdin. Vous pouvez lire depuis sys.stdin comme un fichier. Exemple:

import sys

print sys.stdin.read()

Ce programme sort littéralement son entrée.

10
C0deH4cker

Puisque cette réponse apparaît en haut de Google lorsque vous recherchez piping data to a python script, j'aimerais ajouter une autre méthode, que j'ai trouvée dans Python Cookbook de J. Beazley après avoir recherché un aproach moins «agité» que d'utiliser sys . IMO, plus pythonique et explicite, même pour les nouveaux utilisateurs.

import fileinput
with fileinput.input() as f_input:
    for line in f_input:
        print(line, end='')

Cette approche fonctionne également pour les commandes structurées comme ceci:

$ ls | ./filein.py          # Prints a directory listing to stdout.
$ ./filein.py /etc/passwd   # Reads /etc/passwd to stdout.
$ ./filein.py < /etc/passwd # Reads /etc/passwd to stdout.

Si vous avez besoin de solutions plus complexes, vous pouvez combiner argparse et fileinputcomme indiqué dans ce Gist par martinth :

import argpase
import fileinput

if __== '__main__':
    parser = ArgumentParser()
    parser.add_argument('--dummy', help='dummy argument')
    parser.add_argument('files', metavar='FILE', nargs='*', help='files to read, if empty, stdin is used')
    args = parser.parse_args()

    # If you would call fileinput.input() without files it would try to process all arguments.
    # We pass '-' as only file when argparse got no files which will cause fileinput to read from stdin
    for line in fileinput.input(files=args.files if len(args.files) > 0 else ('-', )):
        print(line)

`` `

3
nlsdfnbch