1

I've installed the Ruby gem 'haml' on my mac, which I can use to compile haml files into html files using the following command at the terminal:

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

This command simply creates an html file at the second path, and gives no output in the terminal. So for example, this command:

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

Creates a sugar.html file at the given path. Now I'm trying to use this functionality from a python script. When I type this into IDLE's interactive 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>

I get output suggesting that the process has been run, however, there is no file outputted. Why is this happening? I even put in the Shell argument, but no interactive shell shows up. Also, I read somewhere that the default shell used is not bash, which is what the Mac terminal uses, so I put that in too for good measure.

Following icktoofay's advice, I ran check_call. Here is the traceback I received:

Traceback (most recent call last):
File "/Users/neil/Desktop/subprocesstest.py", line 7, in p = subprocess.check_call(x, shell=True) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 504, in check_call raise CalledProcessError(retcode, cmd) CalledProcessError: Command 'haml "/Volumes/Macintosh HD/Users/neil/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/neil/Sites/ICSP/sugar.html"' returned non-zero exit status 127

According to the bash reference manual, while searching for a command to be executed,

If the name is neither a shell function nor a builtin, and contains no slashes, Bash searches each element of $PATH for a directory containing an executable file by that name. ... If that function is not defined, the shell prints an error message and returns an exit status of 127.

However, I thought it was indeed finding the haml command after adding the shell and executable arguments, because before that, it was giving a 'file or directory not found error', which indicates that the function is not executable directly but rather in a shell only.

Now how do I make python find this haml command? Or would I have to use some ugly workaround like an applescript which then invokes the haml command.

4
  • 1
    Have you tried using subprocess.check_call instead of directly using subprocess.Popen? Commented Jun 4, 2011 at 20:37
  • Sorry the question seems so long now, but I've tried to provide as much information as possible to make debugging easier. Commented Jun 4, 2011 at 20:59
  • 2
    You've probably tried something like this, but does this work (with the paths changed obviously)? subprocess.check_call(['/path/to/haml', '/your/file.haml', '/your/file.html']) Commented Jun 4, 2011 at 21:03
  • Turns out putting the full path to haml in the original call works perfectly. Now how do I make this device independent, ie, how can I make python find haml? Or should I ask users of the script to put haml into their system path or something? Commented Jun 6, 2011 at 10:43

2 Answers 2

2

I see that you are using, shell=True, so I would have expected things to just work. Checked it locally here with Python 2.7.1 and haml 3.1.1 and I had no problems executing it. There are also some python implementations you might be interested in, PyHAML, HamlPy, djaml or django-haml.

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

% cat hello.html
<strong class='code' id='message'>Hello, World!</strong>
Sign up to request clarification or add additional context in comments.

2 Comments

I did actually use the shell=True argument. I'll try using the full path to haml, but since I'm guessing this would vary from computer to computer, it would be difficult to turn this into a distributable script. Also, I did look up the python implementations earlier, but it seems like they're not just a python bridge to call the haml compiler, they actually handle the compiling themselves, sometimes resulting in a different output than the official haml gem's output. I'd rather not risk using a python implementation that might fall behind in syntax support in the future.
@Neil ah I see that now. Should just work then. Very odd. Maybe a bug with haml? I just tested it and it works fine for me.
0

shlex.split() is your friend, when you want to build args list suitable for Popen and its ilk.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.