2016-11-02 4 views
2

Я новичок в Python и не использовал Linux в годы, поэтому я не уверен, где я запутался. Я пытаюсь использовать Popen для запуска sql-файлов в MySQL на Ubuntu.проблема с python с popen и mysql

Вот соответствующий код:

command = ['mysql', '-uUSER', '-pPWD','-h192.168.1.132', '--database=dbName', '<', './1477597236_foo.sql' ] 
print("command is: "+subprocess.list2cmdline(command)) 

proc = subprocess.Popen(
    command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd='.' 
) 

выход из этого то же самое, как если бы был бежать «MySQL --help». Меня озадачивает то, что если я возьму команду output подпроцессом.list2cmdline и запустим ее напрямую, она будет работать отлично. Кроме того, если я заменяю '< file.sql''-e select * from foo', он запускается. Таким образом, '<' и файл вызывают мою проблему. Я знаю, ЧТО это вызывает проблему, но ничего, что я пробовал до сих пор, не исправил ее.

ТИА, Крэйг

ответ

4

Когда Перенаправление или труба или встроенная команда присутствует в командной строке, shell=True требуется. Однако в простых случаях, например, shell=True является излишним. Существует намного более чистый способ избежать shell=True, который дает лучший контроль над входным файлом.

  • если входной файл не существует, то вы получите исключение , прежде чем достижения подпроцесс, который легче обрабатывать
  • процесс запускается без оболочки: лучше портативности & производительности

код:

command = ['mysql', '-uUSER', '-pPWD','-h192.168.1.132', '--database=dbName' ] 

with open('./1477597236_foo.sql') as input_file: 
    proc = subprocess.Popen(
     command, stdin = input_file, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 
    output,error = proc.communicate() 

(я добавил следующую строку, которая должна быть communicate call: поскольку оба stdout & stderr перенаправлены, это единственный простой способ избежать взаимоблокировок между обоими потоками).

+1

И последний вариант - не использовать 'subprocess' вообще: http://stackoverflow.com/questions/372885/how-do-i-connect-to-mysql-database-in-python – mgilson

+0

Типичное меня: ответ на низкоуровневом, с видом на большую картину. Тем не менее мой ответ охватывает случай, когда перенаправление ввода требуется для команды, sql или другой. Хорошая точка зрения. –

+0

У меня были некоторые другие проблемы для работы, но этот ответ Жан-Франсуа Фабре заставил меня на правильном пути. Спасибо всем! –

0

Так что вам нужно добавить shell=True к вашему Popen вызова. < является частью оболочки, и вы не можете использовать функции оболочки без этого параметра.

proc = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd='.',shell=True)