views:

236

answers:

3

The code below is outdated in python 3.0 by being replaced by subprocess.getstatusoutput().

import commands
(ret, out) = commands.getstatusoutput('some command')
print ret
print out

The real question is what's the multiplatform alternative to this command from Python because the above code does fail ugly under Windows because getstatusoutput is supported only under Unix and Python does not tell you this, instead you get something like:

>test.py
1
'{' is not recognized as an internal or external command,
operable program or batch file.
+1  A: 

I wouldn't really consider this multiplatform, but you can use subprocess.Popen:

import subprocess
pipe = subprocess.Popen('dir', stdout=subprocess.PIPE, shell=True, universal_newlines=True)
output = pipe.stdout.readlines()
sts = pipe.wait()
print sts
print output


Here's a drop-in replacement for getstatusoutput:

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell."""
    """This new implementation should work on all platforms."""
    import subprocess
    pipe = subprocess.Popen(cmd, shell=True, universal_newlines=True,
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = str.join("", pipe.stdout.readlines()) 
    sts = pipe.wait()
    if sts is None:
        sts = 0
    return sts, output

This snippet was proposed by the original poster. I made some changes since getstatusoutput duplicates stderr onto stdout.


The problem is that dir isn't really a multiplatform call but subprocess.Popen allows you to execute shell commands on any platform. I would steer clear of using shell commands unless you absolutely need to. Investigate the contents of the os, os.path, and shutil packages instead.

import os
import os.path
for rel_name in os.listdir(os.curdir):
  abs_name = os.path.join(os.curdir, rel_name)
  if os.path.isdir(abs_name):
    print('DIR:  ' + rel_name)
  elif os.path.isfile(abs_name):
    print('FILE: ' + rel_name)
  else:
    print('UNK?  ' + rel_name)
D.Shawley
Thanks. I think you did not used community wiki option because I was not able to update your answer. I added another one instead.
Sorin Sbarnea
It is marked as a community wiki, but I think that your reputation has to exceed 100 before you can edit ;)
D.Shawley
Ooh, In this case can you update your solution with the code I posted on the last answer so I can accept the response and cleanup the question? Thanks.
Sorin Sbarnea
A: 

getstatusoutput docs say it runs the command like so:

{ cmd } 2>&1

Which obviously doesn't work with cmd.exe (the 2>&1 works fine if you need it though).

You can use Popen as above, but also include the parameter 'stderr=subprocess.STDOUT' to get the same behaviour as getstatusoutput.

My tests on Windows had returncode set to None though, which is not ideal if you're counting on the return value.

JimG
+1  A: 

This would be the multiplatform implementation for getstatusoutput():

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell."""
    """This new implementation should work on all platforms."""
    import subprocess
    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)  
    output = "".join(pipe.stdout.readlines()) 
    sts = pipe.returncode
    if sts is None: sts = 0
    return sts, output
Sorin Sbarnea