在Python中使用Ruby Gem/命令

1 投票
2 回答
1217 浏览
提问于 2025-04-16 18:57

我在我的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"

会在指定的路径下创建一个叫做sugar.html的文件。现在我想在一个Python脚本里使用这个功能。当我在IDLE的交互式Python环境中输入这个命令:

>>>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参数,但没有出现交互式的shell。此外,我还看到有地方说默认使用的shell不是bash,而Mac终端用的是bash,所以我也把这个加上了,以防万一。

根据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行,
raise 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参考手册,在寻找要执行的命令时,

如果这个名字既不是shell函数也不是内置命令,并且不包含斜杠,Bash会在$PATH的每个元素中搜索一个包含该名称的可执行文件的目录。... 如果这个函数没有定义,shell会打印错误信息并返回退出状态127。

不过,我觉得在加上shell和可执行参数后,它确实找到了haml命令,因为之前它给出的错误是'找不到文件或目录',这说明这个命令不能直接执行,而是只能在shell中执行。

现在我该怎么让Python找到这个haml命令呢?还是说我必须使用一些麻烦的变通方法,比如用苹果脚本来调用haml命令。

2 个回答

0

shlex.split() 是一个很有用的工具,当你想要创建一个适合 Popen 及类似功能的 args 列表时,它会帮你大忙。

>>> 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
2

我看到你在使用 shell=True,所以我本来以为一切都会正常运行。我在本地用 Python 2.7.1 和 haml 3.1.1 测试过,执行的时候没有遇到任何问题。还有一些 Python 的实现你可能会感兴趣,比如 PyHAMLHamlPydjaml 或者 django-haml

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

% cat hello.html
<strong class='code' id='message'>Hello, World!</strong>

撰写回答