【问题标题】:Using ruby gem/command from python使用来自 python 的 ruby​​ gem/command
【发布时间】:2011-09-08 12:20:20
【问题描述】:

我已经在我的 Mac 上安装了 Ruby gem '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 shell 中输入这个:

>>>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 终端使用的,所以我把它也放进去了。

按照 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 "/卷/麦金塔 高清/用户/尼尔/站点/ICSP/sugar.haml" "/卷/麦金塔 高清/用户/尼尔/站点/ICSP/sugar.html"' 返回非零退出状态 127

根据bash reference manual,在搜索要执行的命令时,

如果名称既不是shell 函数也不是内置函数,并且包含 没有斜线,Bash 搜索每个元素 的 $PATH 用于包含 该名称的可执行文件。 ... 如果 该功能未定义, shell 打印一条错误消息并且 返回退出状态 127。

但是,我认为在添加shell和可执行参数后确实找到了haml命令,因为在此之前,它给出了“找不到文件或目录错误”,这表明该函数不能直接执行,而是仅在外壳中。

现在如何让python找到这个haml命令?或者我是否必须使用一些丑陋的解决方法,例如调用 haml 命令的 applescript。

【问题讨论】:

  • 你试过用subprocess.check_call而不是直接用subprocess.Popen吗?
  • 抱歉,这个问题现在看来已经很久了,但我已经尽力提供尽可能多的信息以使调试更容易。
  • 您可能已经尝试过类似的方法,但这是否有效(路径明显改变)? subprocess.check_call(['/path/to/haml', '/your/file.haml', '/your/file.html'])
  • 原来在原始调用中放置到haml的完整路径非常有效。现在如何让这个设备独立,即如何让python找到haml?还是我应该要求脚本的用户将haml放入他们的系统路径或其他东西?

标签: python shell command subprocess haml


【解决方案1】:

我看到你正在使用shell=True,所以我本来希望事情能正常工作。使用 Python 2.7.1 和 haml 3.1.1 在本地检查它,执行它没有问题。还有一些你可能感兴趣的 python 实现,PyHAMLHamlPydjamldjango-haml

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

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

【讨论】:

  • 我确实使用了shell=True 参数。我将尝试使用haml的完整路径,但由于我猜测这会因计算机而异,因此很难将其转换为可分发的脚本。另外,我之前确实查看了 python 实现,但似乎它们不仅仅是调用 haml 编译器的 python 桥,它们实际上自己处理编译,有时会导致与官方 haml gem 的输出不同的输出。我宁愿不要冒险使用将来可能在语法支持方面落后的 python 实现。
  • @Neil 啊我现在明白了。那时应该工作。很奇怪。也许是haml的错误?我刚刚对其进行了测试,对我来说效果很好。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-23
    • 2011-04-11
    • 2014-10-03
    • 2016-12-13
    • 2016-09-17
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多