Използване на ruby ​​gem/команда от python

Инсталирах Ruby gem 'haml' на моя Mac, който мога да използвам, за да компилирам 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"

Създава файл sugar.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: Команда '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
@Neil ах сега го виждам. Тогава просто трябва да работи. Много странно. Може би грешка с haml? Току-що го тествах и работи добре за мен. - 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