Consider the following script

#!/usr/bin/env python
# foo.py
import sys
print sys.argv

When I run this in a terminal with arguments, here is the output

$ ./foo.py -h hello -m "this is a string"
['./foo.py', '-h', 'hello', '-m', 'this is a string']

My question is: is there a function in python's standard library, which, given the string ./foo.py -h hello -m "this is a string" produces the list ['./foo.py', '-h', 'hello', '-m', 'this is a string'] in the same way as the interpreter does when it builds sys.argv ?

I don't think so.
This function is implemented in C based on the stdlib's int argc and char** argv variables.
Look at the makeargvobject function.

Thanks, I'll check that.

I have a poor man's solution, which uses a subprocess: I pass the string as the arguments of a subprocess which prints it's argv...

>>> import subprocess as sp
>>> def parse(s):
...  return eval(sp.Popen('./foo.py '+s, shell=True, stdout=sp.PIPE).communicate()[0])[1:]
>>> 
>>> parse('myprog -c hello -m "this is a string"')
['myprog', '-c', 'hello', '-m', 'this is a string']

I found a nice solution which uses the module pygment (which implements syntax highlighting for different languages). Pygment contains a lexer for the bash shell. So, here is the result of an interactive session with python:

>>> from pygments.lexers import get_lexer_by_name
>>> lexer = get_lexer_by_name("bash")
>>> L=list(lexer.get_tokens_unprocessed('./foo.py -c hello -m "this is a string"'))
>>> L
[(0, Token.Text, './foo.py'), (8, Token.Text, ' '), (9, Token.Text, '-c'), (11, Token.Text, ' '), (12, Token.Text, 'hello'), (17, Token.Text, ' '), (18, Token.Text, '-m'), (20, Token.Text, ' '), (21, Token.Literal.String.Double, '"this is a string"')]

The arguments are easily extracted from this list. It doesn't work exactly as argv, because shell expansions (for ~, $variable, *) are not processed. They must be done using os.path.expanduser and related functions.

I am happy, I was right. There is no standard lib function that does that.

Can you tell us why you need that?

I am happy, I was right. There is no standard lib function that does that.

Can you tell us why you need that?

Yes, I'm trying to create a nice subclass of cmd.Cmd which can be used to write command interpreters. A small command line interpreter can be very useful to manage a project. So I'm just refactoring some code to create a module which gives you readily an extensible interpreter. I think this module should have a general way to handle command lines. I'll post here a link to the module when it will be available. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.