Вывод трубы из командной строки в сценарий python
Я хочу запустить команду mysql
и установить вывод этой переменной в мой скрипт python.
Вот команда оболочки, которую я пытаюсь запустить:
$ mysql my_database --html -e "select * from limbs" | ./script.py
Вот скрипт python:
#!/usr/bin/env python
import sys
def hello(variable):
print variable
Как я могу принять переменную в скрипте python и распечатать ее?
Ответы
Ответ 1
Вам нужно прочитать stdin для извлечения данных в скрипте python, например
#!/usr/bin/env python
import sys
def hello(variable):
print variable
data = sys.stdin.read()
hello(data)
Если все, что вы хотите сделать, это захватить некоторые данные из базы данных mysql, а затем манипулировать им с помощью Python, я бы пропустил его в сценарий и просто использовал модуль MySql Python для выполнения SQL-запроса.
Ответ 2
Если вы хотите, чтобы ваш скрипт вел себя как много инструментов командной строки unix и принимал трубку или имя файла в качестве первого аргумента, вы можете использовать следующее:
#!/usr/bin/env python
import sys
# use stdin if it 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
Ответ 3
Когда вы подаете вывод одной команды в скрипт pytho, она переходит к sys.stdin. Вы можете читать sys.stdin так же, как файл. Пример:
import sys
print sys.stdin.read()
Эта программа буквально выводит свой вклад.
Ответ 4
Поскольку этот ответ появляется в Google наверху при поиске piping data to a python script
, я хотел бы добавить еще один метод, который я нашел в Поварской книге J. Beazley Python после поиска менее "серьезного" подхода, чем использование sys
. IMO, более pythonic и понятным даже для новых пользователей.
import fileinput
with fileinput.input() as f_input:
for line in f_input:
print(line, end='')
Этот подход также работает для команд, структурированных следующим образом:
$ 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.
Если вам требуются более сложные решения, вы можете сопоставить argparse
и fileinput
как показано в этом вопросе, с помощью 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)
"""
Ответ 5
Это старый вопрос, но если вы на bash, и ваш скрипт имеет что-то вроде
import sys
x = sys.argv[1]
print x
и вы хотите передать вывод из команды, выполненной в оболочке, в sys.argv [], вы можете сделать это с помощью
test.py $(some_command -w arguments)
Если вы ожидаете одну строку от вашего вывода, она будет передана обратно как argv [1]. Если вы ожидаете нескольких строк, они будут передаваться по отдельности и помещаться в массив argv [], и если вы хотите проверить содержимое, которое вы сделали бы
print sys.argv[1:] #starting at index 1 so you don't get the script name in the output
Если это тип вывода, который будет возвращен как массив, вам придется изменить свой скрипт python, чтобы получить весь вывод, помещенный в один вызываемый объект. Есть способы, упомянутые выше, но вы также можете просто вызвать команду непосредственно в своем скрипте и сохранить вывод в переменной с помощью
import subprocess
x = subprocess.check_output('mysql my_database --html -e "select * from limbs"',shell=True)
print x
которые выходят
whatever_output
came_from_the
command_execution
in_the_same_format
* операторы печати произвольны и просто выбраны для отображения значений
Я хотел добавить это в список ответов, потому что это полезно, когда вы хотите вызывать несколько программ для их вывода, а не для каждого из них по отдельности.