Simon TheChain
Simon TheChain

Reputation: 277

Python 2 subprocess arguments error under Mac

I'm trying to do a Mac version of a program that runs fine under Windows, using python 2.7. Under Mac (OS X El Capitan running in VirtualBox), it fails because the arguments I pass to the shell are not recognized properly.

Original code:

for item in source_files:

    # core process
    output = sub.Popen(["mhl", "verify", "-vv", "-f", item, ">", text_report],
                       shell=True,
                       stdout=sub.PIPE,
                       stderr=sub.PIPE)
    stdout_value, stderr_value = output.communicate()

Under Mac only the 'mhl' argument is recognized so I tried this:

sub.Popen(['mhl verify -vv -f', item, '>', text_report]

Now the command works but the item (a .mhl file) is not recognized so I tried this:

sub.Popen(['mhl verify -vv -f', '/Users/simon/Documents/Documents.mhl', '>', text_report]

and this:

sub.Popen(['mhl verify -vv -f', r'/Users/simon/Documents/Documents.mhl', '>', text_report]

Same results, it tells me a mhl file should follow the '-f' argument. If I add the item directly to the first argument it works fine:

sub.Popen(['mhl verify -vv -f /Users/simon/Documents/Documents.mhl', '>', text_report]

What am I missing here?

Upvotes: 0

Views: 295

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1125068

You are asking the OS to run the executable 'mhl verify -vv -f', and there is no such executable. No shell splitting takes place on the spaces there.

With shell=True you'd want to pass in everything as one string, not as separate arguments:

sub.Popen('mhl verify -vv -f {} > {}'.format(item, text_report),
          shell=True, stdout=sub.PIPE, stderr=sub.PIPE)

Note that there is little point in directing stdout to a pipe here, since all stdout output from the mhl command is being redirected to a file.

If you wanted to capture the output of the mhl command directly in Python, I'd not use a shell intermediary here; run without shell=True and then just use subprocess.check_output() to retrieve the output:

output = sub.check_output(['mhl', 'verify', '-vv', '-f', item])

Note that now the program name and the arguments must be passed in ready-split into separate strings.

Upvotes: 1

Related Questions