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?
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.
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
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.
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 fileinput
comme 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)
`` `