commands – Run external shell commands

Purpose:The commands module contains utility functions for working with shell command output under Unix.
Available In:1.4

Warning

This module is made obsolete by the subprocess module.

There are 3 functions in the commands module for working with external commands. The functions are shell-aware and return the output or status code from the command.

getstatusoutput()

The function getstatusoutput() runs a command via the shell and returns the exit code and the text output (stdout and stderr combined). The exit codes are the same as for the C function wait() or os.wait(). The code is a 16-bit number. The low byte contains the signal number that killed the process. When the signal is zero, the high byte is the exit status of the program. If a core file was produced, the high bit of the low byte is set.

from commands import *

def run_command(cmd):
    print 'Running: "%s"' % cmd
    status, text = getstatusoutput(cmd)
    exit_code = status >> 8 # high byte
    signal_num = status % 256 # low byte
    print 'Status: x%04x' % status
    print 'Signal: x%02x (%d)' % (signal_num, signal_num)
    print 'Exit  : x%02x (%d)' % (exit_code, exit_code)
    print 'Core? : %s' % bool(signal_num & (1 << 8)) # high bit
    print 'Output:'
    print text
    print

run_command('ls -l *.py')
run_command('ls -l *.notthere')
run_command('./dumpscore')
run_command('echo "WAITING TO BE KILLED"; read input')

This example runs two commands that exit normally, a third meant to generate a core dump, and a fourth that blocks waiting to be killed from another shell. (Don’t simply use Ctrl-C as the interpreter will intercept that signal. Use ps and grep in another window to find the read process and send it a signal with kill.)

$ python commands_getstatusoutput.py
Running: "ls -l *.py"
Status: x0000
Signal: x00 (0)
Exit  : x00 (0)
Core? : False
Output:
-rw-r--r--  1 dhellmann  dhellmann  1140 Mar 12  2009 __init__.py
-rw-r--r--  1 dhellmann  dhellmann  1297 Mar 12  2009 commands_getoutput.py
-rw-r--r--@ 1 dhellmann  dhellmann  1355 Mar 12  2009 commands_getstatus.py
-rw-r--r--@ 1 dhellmann  dhellmann  1739 Nov 26 12:52 commands_getstatusoutput.py

Running: "ls -l *.notthere"
Status: x0100
Signal: x00 (0)
Exit  : x01 (1)
Core? : False
Output:
ls: *.notthere: No such file or directory

Running: "./dumpscore"
Status: x8600
Signal: x00 (0)
Exit  : x86 (134)
Core? : False
Output:
sh: line 1: 47021 Abort trap              (core dumped) ./dumpscore

Running: "echo "WAITING TO BE KILLED"; read input"
Status: x0001
Signal: x01 (1)
Exit  : x00 (0)
Core? : False
Output:
WAITING TO BE KILLED

In this example, I used kill -HUP $PID to kill the reading process from a separate shell window, so the signal is reported as 1.

getoutput()

If the exit code is not useful for your application, you can use getoutput() to receive only the text output from the command.

from commands import *

text = getoutput('ls -l *.py')
print 'ls -l *.py:'
print text

print 

text = getoutput('ls -l *.notthere')
print 'ls -l *.py:'
print text
$ python commands_getoutput.py
ls -l *.py:
-rw-r--r--   1 dhellman  dhellman  1191 Oct 21 09:41 __init__.py
-rw-r--r--   1 dhellman  dhellman  1321 Oct 21 09:48 commands_getoutput.py
-rw-r--r--   1 dhellman  dhellman  1265 Oct 21 09:50 commands_getstatus.py
-rw-r--r--   1 dhellman  dhellman  1626 Oct 21 10:10 commands_getstatusoutput.py

ls -l *.py:
ls: *.notthere: No such file or directory

getstatus()

Contrary to what you might expect, getstatus() does not run a command and return the status code. Instead, it’s argument is a filename which is combined with “ls -ld” to build a command to be run by getoutput(). The text output of the command is returned.

from commands import *

status = getstatus('commands_getstatus.py')
print 'commands_getstatus.py:', status
status = getstatus('notthere.py')
print 'notthere.py:', status
status = getstatus('$filename')
print '$filename:', status

As you notice from the output, the $ character in the argument to the last call is escaped so the environment variable name is not expanded.

$ python commands_getstatus.py
commands_getstatus.py: -rw-r--r--   1 dhellman  dhellman  1387 Oct 21 10:19 commands_getstatus.py
notthere.py: ls: notthere.py: No such file or directory
$filename: ls: $filename: No such file or directory

See also

commands
The standard library documentation for this module.
signal
Defines constants for signals such as HUP (1).