outputting a command to the terminal?

Steven Bethard steven.bethard at gmail.com
Mon Aug 14 13:06:07 EDT 2006


John Salerno wrote:
> Steven Bethard wrote:
>> ---------------------------- scriptname.py ----------------------------
>> import argparse # http://argparse.python-hosting.com/
>> import subprocess
>> import sys
>>
>> def outputfile(filename):
>>     return open(filename, 'w')
>>
>> if __name__ == '__main__':
>>     # parse the command line arguments
>>     parser = argparse.ArgumentParser()
>>     parser.add_argument('packages', metavar='package', nargs='+',
>>                         help='one of the packages to install')
>>     parser.add_argument('--save', type=outputfile, default=sys.stdout,
>>                         help='a file to save the package names to')
>>     namespace = parser.parse_args()
>>
>>     # call the command
>>     command = ['sudo', 'aptitude', 'install'] + namespace.packages
>>     subprocess.call(command)
>>
>>     # write the package name file
>>     for package_name in namespace.packages:
>>         namespace.save.write('%s\n' % package_name)
>> -----------------------------------------------------------------------
>>
>>
>> $ scriptname.py -h
>> usage: scriptname.py [-h] [--save SAVE] package [package ...]
>>
>> positional arguments:
>>   package      one of the packages to install
>>
>> optional arguments:
>>   -h, --help   show this help message and exit
>>   --save SAVE  a file to save the package names to
>
> 
> yikes! I'll have to take some time to study this! I appreciate it. :)


For just calling the command, the important lines are::

     command = ['sudo', 'aptitude', 'install'] + namespace.packages
     subprocess.call(command)

where you could have probably used ``sys.argv[1:]`` instead of 
namespace.packages.


For writing the file, as I'm sure you've already figured out, the 
important lines are::

     for package_name in namespace.packages:
         namespace.save.write('%s\n' % package_name)

where again, if you weren't using argparse, you could have used 
``sys.argv`` to determine the package names (namespace.packages) and the 
file to write to (namespace.save).


The remaining lines involving the ``parser`` object are basically 
defining a command line interface in a similar way to what optparse in 
the stdlib does.  Sure, you could do all of this by fiddling with 
sys.argv, but the argparse module will do all the parsing and 
conversions for you, and give your script a meaningful usage message. 
And I'm a firm believer in meaningful usage messages. =)

STeVe

P.S. Thank *you* for posting this.  As a result, I've been convinced 
that argparse should grow a 'outfile' type, something I've been debating 
with myself about for a while now.



More information about the Python-list mailing list