john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

command line arguments argv parameters parsing argparse

[TOC]

Getting input and shelling out are both fairly normal tasks for programs that have to interact with a user or the operating system.

argparse to get command line parameters

import sys
import argparse

parser = argparse.ArgumentParser()
parser.add_argument( '-V', '--verbose', help='increase output verbosity', action="store_true" ) # make it a boolean type
parser.add_argument( 'number', help='squares a number', type=int )
args = parser.parse_args()

if args.verbose:
  print '{0} {1} * {1}'.format( sys.argv[0], args.number )

print args.number**2


# python example.py 2           # output 4
# python example.py --verbose 2     # output 2 * 2 , 4  # boolean optional parameter

# action="count"    # count the number of times the argument is used, e.g. -VV , args.verbose == 2
# parser.add_argument( "-V", "--verbosity", action="count", default=0, help='increase output verbosity' )

# group = parser.add_mutually_exclusive_group()
# group.add_argument( "-V", "--verbose", action="store_true" )
# group.add_argument( "-q", "--quiet", action="store_true" )

subprocess to send commands to the shell

import subprocess
mystrings = list()
mystrings.append( 'ls' )                   # normal stuff just in single quotes
mystrings.append( '-ahl' )                 # normal stuff just in single quotes
mystrings.append( 'name with space.txt' )  # multiple items together if they require escaping in the shell
p = subprocess.Popen( mystrings )


check_call( ['ls', '-l'] )      # convenience wrapper that returns True if the exit code was 0, otherwise raise CalledProcessError


p = subprocess.Popen( mystrings )
(stdout_data,stderr_data) = p.communicate()    # tuple returns

# Popen.stdin  If the stdin argument was PIPE, this attribute is a file object that provides input to the child process. Otherwise, it is None.
# Popen.stdout If the stdout argument was PIPE, this attribute is a file object that provides output from the child process. Otherwise, it is None.
# Popen.stderr If the stderr argument was PIPE, this attribute is a file object that provides error output from the child process. Otherwise, it is None.

subprocess call wrapper

from subprocess import call
import time
try:
  while True:
    call( ["ls", "-l"] )    # subprocess.call is a blocking wrapper of Popen
    time.sleep( 2 )
except KeyboardInterrupt:
  pass
print '\ndone'

- - -
from subprocess import Popen, PIPE

data = Popen(['/usr/bin/dpkg', "-l"], stdout=PIPE).communicate()[0]
# print len(data)
lines = data.split('ii')
print len(lines)
for i in lines:
    if "ssl" in i:
        print i.strip()

keyword = ''
output = Popen(['ps', '-ef'], stdout=PIPE).communicate()[0]
lines = output.split('\n')
for i in lines:
  if keyword in i:
    print i.strip()


from subprocess import Popen, PIPE
# get process listing but exclude vi

keyword = 'someapp'
exclude = 'vi'
output = Popen(['ps', '-ef'], stdout=PIPE).communicate()[0]
# print output
lines = output.split('\n')
# print len(lines)

targets = list()
for i in lines:
  if keyword in i:
    parts = i.strip().split()
    excluded = False
    for k in parts:
      if k.strip() == exclude:
        excluded = True
    if not excluded:
      targets.append(i.strip())

for i in targets:
  print i

subprocess Popen replacing shell pipes and os.system()

output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]        # replace shell `

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)           # replace shell |
output = p2.communicate()[0]

p = Popen("mycmd" + " myarg", shell=True)                   # replace os.system()
sts = os.waitpid(p.pid, 0)[1]

try:
    retcode = call("mycmd" + " myarg", shell=True)              # better replacement of os.system()
    if retcode < 0:
        print >>sys.stderr, "Child was terminated by signal", -retcode
    else:
        print >>sys.stderr, "Child returned", retcode
except OSError, e:
    print >>sys.stderr, "Execution failed:", e

- - -
#!/usr/bin/env python
# search $PATH for python executable environment to run this script

import os
import sys
import subprocess


def get_result( command ):
    """ Send a command to the os shell and get the result as a string. """

    stringList = command.rsplit()

#   for word in stringList:
#       print word          # DEBUG
#   print ""

    p = subprocess.Popen( stringList , shell = True , stdout = subprocess.PIPE )

    linesum = ""
    while True:
        inline = p.stdout.readline()
        if not inline:
            break
        linesum += inline

    return linesum


if __name__ == '__main__':
        print "{} arguments passed in: {}".format( len(sys.argv) , sys.argv )
    print "type in a command like 'echo hi' "
    test = sys.stdin.readline()
    result = get_result( test )
    sys.stdout.write( result )
    print "your command result output saved as a string printed again: " , result
    sys.stdout.flush()
    print ""

subprocess sending a command to bash -c

import sys
import os
import subprocess

cmd = ['/usr/bin/sudo', '/bin/bash', '-c', 'touch /root/foobar']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
my_output, err = p.communicate()
print(my_output)
print(err)

argparse examples

#!/usr/bin/env python
import argparse
parser = argparse.ArgumentParser()

# SIMPLEST EXAMPLE
# parser.parse_args()
# ./example.py test # returns: usage example.py [-h] , unrecognized arguments: test


# SIMPLE EXAMPLE
# parser.add_argument( 'number', help='squares a number', type=int ) # default type is string
# args = parser.parse_args()
# print args.number**2


# OPTIONAL ARGUMENT EXAMPLE
parser = argparse.ArgumentParser()
parser.add_argument( '-V', '--verbose', help='increase output verbosity' )
parser.add_argument( 'number', help='squares a number', type=int )

args = parser.parse_args()
if args.verbose:
  print '{0} * {0}'.format( args.number )
print args.number**2

# ./example.py          # output usage: parser.py [-h] [-V VERBOSE] number , example.py: error: too few arguments
# ./example.py 2        # output 4
# ./example.py -V=true 2    # output 2 * 2 , 4
# ./example.py -V 1 2       # output 2 * 2 , 4
# ./example.py --verbose=foo 2  # output 2 * 2 , 4
# ./example.py --verbose 1 2    # output 2 * 2 , 4

Miscellaneous argparse and subprocess examples

import argparse
import time
import sys
import os
import subprocess


if __name__ == '__main__':      # only currently works on win7?
    try:
        start_time = time.time()
    parser = argparse.ArgumentParser( description='Process some integers.' )
    parser.add_argument( 'integers' , metavar = 'N' , type = int , nargs = '+' , help = 'an integer for the accumulator' )
    parser.add_argument( '--sum' , dest = 'accumulate' , action = 'store_const' , const = sum , default = max ,
                   help = 'sum the integers (default: find the max)' )

    args = parser.parse_args()
    print args.accumulate( args.integers )

    print "type in a command like 'echo hi' "
        user_input = sys.stdin.readline()
        stringList = user_input.rsplit()

        i = 0
    for word in stringList:         # DEBUG
            print "%s word" % i
                i = i + 1

    p = subprocess.Popen( stringList , shell = True , stdout = subprocess.PIPE )

        linesum = ""
        while True:
        inline = p.stdout.readline()
        if not inline:
            break
        linesum += inline

        print "On linux stdout readline isn't working, otherwise this prints 'hi' , " , str( linesum )
        elapsed_time = time.time() - start_time
    print "Hi World! Done in %s seconds \n" % elapsed_time

    except KeyboardInterrupt, e: # Ctrl-C
        raise e

- - -
# usage: python myappcfg.py  , only currently works on win7

import argparse
import os
from subprocess import call


def main( **kwargs ):

    if( kwargs ):
        for key, value in kwargs.iteritems():
            print "key=" + str( key ) + " value=" + str( value )

#   cmd = '{0} {1}'.format(kwargs['program'], ' '.join(kwargs['infiles']))


    # os.path.splitunc( path )  # for network shares
    root = os.path.splitdrive( os.getcwd() )[0]     # first element of the list
    if( root == "" ):
        print "linux system " , os.name

    root = os.path.join( root , os.path.sep )
    # print "root is " + root       # DEBUG


    if( os.name == "nt" ):
        appengine_directory = os.path.join( root , "progra~2" , "google" , "google_appengine" )
        # ~2 is the 32bit x86 program files in dos compatible path mode (no spaces in names)

    print appengine_directory

    appengine_script = os.path.join( appengine_directory , "appcfg.py" )
    print "executing: python " + appengine_script   # DEBUG
#   call( ["python" , str( appengine_script ) ] )



if __name__ == "__main__":

    try:
        parser = argparse.ArgumentParser( description = 'appcfg.py action application_name' )
        parser.add_argument( '--command' , type = str , help = 'appcfg action command' )
        parser.add_argument( '--application_name' , type = str , help = 'application name' )
#       parser.add_argument( 'application' , type = str , help = 'application name' )

        args = parser.parse_args()
        main( **vars(args) )    # sends arguments to main as a key value pair dictionary


    except KeyboardInterrupt, e: # Ctrl-C
        raise e

- - -

# Assumes: sudo pip install pip2pi s3cmd; sudo pip2tgz /tmp jasmine
# downloads: jasmine-2.0.0.tar CherryPy-3.2.5.tar.gz  etc.
# s3cmd --config $HOME/.s3cfg put /tmp/index.html s3://mybucket/python/simple/PACKAGE/index.html
# expects all the directories are created, TODO: s3cmd createdir

import os
import subprocess

packages = list()
for i in os.listdir('/tmp'):
  if os.path.isfile(i) and i.endswith('tar.gz'):
    packages.append(i)

packages.sort()
print len(packages)

for i in packages:
    package_name_parts = i.rsplit('-',1)  # covers a package name like pytest-cov-1.6.tar.gz
    package_name = package_name_parts[0]

    with open('/tmp/index.html', 'w') as f:
      print f.write('<a href="' + i + '">' + i + '</a><br />')
    myargs = '/usr/bin/s3cmd ls s3://mybucket/python/simple/' + package_name + '/'
    # myargs = '/usr/bin/s3cmd put ' + i + ' s3://mybucket/python/simple/' + package_name + '/'
    print myargs
    command_list = myargs.split()
    p = subprocess.Popen(command_list, stdout=subprocess.PIPE)
    my_data, my_err = p.communicate()
    print my_data

  • « Ntp ntpd server client
  • redirect a webpage permenantly 301 »

Published

Oct 15, 2014

Category

python

~1093 words

Tags

  • argparse 1
  • arguments 4
  • argv 3
  • command 29
  • line 31
  • parameters 15
  • parsing 2
  • python 180