Canalizar la salida del comando de shell a un script de python

Quiero ejecutar un comando mysql y establecer que la salida sea una variable en mi script de python.

Aquí está el comando de shell que estoy tratando de ejecutar:

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

Aquí está la secuencia de comandos de python:

 #!/usr/bin/env python import sys def hello(variable): print variable 

¿Cómo aceptaría la variable en el script de python y le pido que imprima la salida?

Debe leer desde la entrada estándar para recuperar los datos en el script de python, por ejemplo

 #!/usr/bin/env python import sys def hello(variable): print variable data = sys.stdin.read() hello(data) 

Si todo lo que quieres hacer aquí es tomar algunos datos de una base de datos mysql y luego manipularlos con Python, me gustaría omitirlos en el script y solo usar el módulo MySQL de Python para realizar la consulta SQL.

Si desea que su script se comporte como muchas herramientas de línea de comandos de Unix y acepte una canalización o un nombre de archivo como primer argumento, puede usar lo siguiente:

 #!/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 

Cuando canaliza la salida de un comando a un script de Pytho, va a sys.stdin. Puedes leer desde sys.stdin como un archivo. Ejemplo:

 import sys print sys.stdin.read() 

Este progtwig literalmente genera su entrada.

Ya que esta respuesta aparece en Google en la parte superior al buscar piping data to a python script , me gustaría agregar otro método, que he encontrado en el Libro de cocina de Python de J. Beazley después de buscar un enfoque menos “valioso” que el uso de sys . OMI, más python y autoexplicativo incluso para los nuevos usuarios.

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

Este enfoque también funciona para comandos estructurados como este:

 $ 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 necesita soluciones más complejas, puede comstackr argparse y fileinput como se muestra en esta idea de martinth :

 import argpase import fileinput if __name__ == '__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) 

`` `

Me topé con esto tratando de canalizar un comando de bash a un script de python que no escribí (y no quería modificar para aceptar sys.stdin ). Encontré la sustitución de procesos mencionada aquí ( https://superuser.com/questions/461946/can-i-use-pipe-output-as-a-shell-script-argument ) para funcionar bien.

Ex. some_script.py -arg1 <(bash command)