Использование рубинового камня/команды из python

Я установил на свой Mac гем Ruby 'haml', который я могу использовать для компиляции haml-файлов в html-файлы с помощью следующей команды в терминале:

haml 'path/to/haml/file.haml' 'desired/html/path/file.html'

Эта команда просто создает html-файл по второму пути и не выводит его в терминал. Так, например, эта команда:

haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"

Создает файл сахара.html по заданному пути. Теперь я пытаюсь использовать эту функциональность из скрипта Python. Когда я ввожу это в интерактивную оболочку Python IDLE:

>>>import subprocess
>>>subprocess.Popen('haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml"        "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"', shell=True, executable='/bin/bash')
<subprocess.Popen object at 0x159d6f0>

Я получаю вывод, предполагающий, что процесс был запущен, однако файл не выводится. Почему это происходит? Я даже указал аргумент Shell, но интерактивная оболочка не появляется. Кроме того, я где-то читал, что используемая оболочка по умолчанию не является bash, которую использует терминал Mac, поэтому я тоже добавил это для верности.

Следуя совету icktoofay, я запустил check_call. Вот трассировка, которую я получил:

Трассировка (последний последний вызов):
Файл "/Users/neil/Desktop/subprocesstest.py", строка 7, в p = subprocess.check_call(x, shell=True) Файл "/Library/Frameworks/Python. framework/Versions/2.7/lib/python2.7/subprocess.py", строка 504, в check_call поднять CalledProcessError(retcode, cmd) CalledProcessError: Command 'haml "/Volumes/Macintosh HD/Users/neil/Sites/ICSP/sugar .haml" "/Volumes/Macintosh HD/Users/neil/Sites/ICSP/sugar.html"' вернул ненулевой статус выхода 127

Согласно справочному руководству по bash, при поиске команды для выполнения ,

Если имя не является ни функцией оболочки, ни встроенной функцией и не содержит косых черт, Bash ищет в каждом элементе $PATH каталог, содержащий исполняемый файл с таким именем. ... Если эта функция не определена, оболочка выводит сообщение об ошибке и возвращает статус выхода 127.

Тем не менее, я думал, что это действительно находит команду haml после добавления оболочки и исполняемых аргументов, потому что до этого она выдавала «файл или каталог не найден», что указывает на то, что функция не является исполняемой напрямую, а скорее в оболочке Только.

Теперь, как мне заставить python найти эту команду haml? Или мне придется использовать какое-то уродливое обходное решение, такое как applescript, который затем вызывает команду haml.


person Neil    schedule 04.06.2011    source источник
comment
Пробовали ли вы использовать subprocess.check_call вместо прямого использования subprocess.Popen?   -  person icktoofay    schedule 05.06.2011
comment
Извините, вопрос кажется таким длинным, но я постарался предоставить как можно больше информации, чтобы упростить отладку.   -  person Neil    schedule 05.06.2011
comment
Вы, вероятно, пробовали что-то подобное, но работает ли это (с очевидным изменением путей)? subprocess.check_call(['/path/to/haml', '/your/file.haml', '/your/file.html'])   -  person icktoofay    schedule 05.06.2011
comment
Оказывается, указание полного пути к haml в исходном вызове работает отлично. Теперь, как мне сделать это устройство независимым, т.е. как я могу заставить python найти haml? Или я должен попросить пользователей сценария поместить haml в системный путь или что-то в этом роде?   -  person Neil    schedule 06.06.2011


Ответы (2)


Я вижу, что вы используете shell=True, поэтому я ожидал, что все будет работать. Проверил это локально здесь с Python 2.7.1 и haml 3.1.1, и у меня не было проблем с его выполнением. Есть также некоторые реализации Python, которые могут вас заинтересовать: PyHAML, HamlPy, djaml или django-haml.

import subprocess
subprocess.Popen(['haml', 'hello.haml', 'hello.html'], shell=True)

% cat hello.html
<strong class='code' id='message'>Hello, World!</strong>
person zeekay    schedule 04.06.2011
comment
Я действительно использовал аргумент shell=True. Я попробую использовать полный путь к haml, но поскольку я предполагаю, что это будет варьироваться от компьютера к компьютеру, будет сложно превратить его в распространяемый сценарий. Кроме того, я просматривал реализации python ранее, но похоже, что они не просто мост python для вызова компилятора haml, они фактически сами выполняют компиляцию, что иногда приводит к результату, отличному от официального вывода haml gem. Я бы не рискнул использовать реализацию Python, которая в будущем может отстать в поддержке синтаксиса. - person Neil; 05.06.2011
comment
@ Нил, а теперь я вижу это. Только тогда должно работать. Очень странно. Может баг с хамлом? Я только что протестировал его, и он отлично работает для меня. - person zeekay; 05.06.2011

shlex.split() — ваш друг, когда вы захотите построить args список подходит для Popen и иже с ним.

>>> import subprocess
>>> import shlex
>>> p = subprocess.Popen(shlex.split('haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"'))
>>> p.wait()
0
person Pavel Repin    schedule 05.06.2011