2012-06-19 3 views
18

Je souhaite exécuter une commande mysql et définir la sortie de cette variable comme étant une variable dans mon script python.Sortie d'un tube depuis la commande shell vers un script python

Voici la commande shell, je suis en train de courir:

$ 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 puis-je accepter la variable dans le script python et avoir l'impression le résultat?

Répondre

19

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

#!/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 à partir d'une base de données MySQL, puis le manipuler avec Python, je sauterais la tuyauterie dans le script et il suffit d'utiliser the Python MySql module pour faire la requête SQL.

+0

+1 pour suggérer mysql-python. – abarnert

9

Lorsque vous redirigez la sortie d'une commande vers un script pytho, elle est transmise à 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.

+1

+1 pour la mention « comme un fichier », qui nous l'espérons mener l'OP à se rendre compte qu'il peut aussi faire des choses comme « pour ligne dans sys.stdin: ", etc. – abarnert

16

Si vous voulez que votre script se comporte comme beaucoup d'outils de ligne de commande unix et accepte un tuyau 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 
2

Depuis cette réponse apparaît sur Google au En haut lorsque je cherche piping data to a python script, je voudrais ajouter une autre méthode, que j'ai trouvée dans J. Beazley's Python Cookbook après avoir cherché une approche moins 'graveleuse' que d'utiliser sys. IMO, plus pythonique et auto-explicatif 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. 
+0

Obtenir une erreur avec cette méthode (en utilisant Python 2.7) retraçage (appel le plus récent en dernier): Fichier "./pipetome.py", ligne 4, dans avec fileinput.input() comme f_input: AttributeError: L'instance de FileInput n'a pas d'attribut '__exit__' –

+0

Ce qui précède n'a été testé que dans Python3 - peut-être au lieu de 'with 'essayez' f_input = fileinput.input() '? – nlsdfnbch

Questions connexes