4

I have a python 2.7 script reading in input arguments through sys.argv[1:]. In order for the input arguments not to be broken up, there has to be quotes around it (otherwise sys.argv will break up the input arguments anywhere there is a space). How do I make sure that there are quotes surrounding it?

Example:

python example.py -copyDir --dir:"C:\Users\heinst\Documents\heinsts music"

Is there a way to check that the --dir: argument has quotes around it? otherwise the list sys.argv would break it up into two parts: C:\Users\heinst\Documents\heinsts and music

heinst
  • 8,520
  • 7
  • 41
  • 77
  • 1
    Keep in mind that it there are no spaces you don't need the quotes and on Linux instead of quoting the path it is normal to escape the space e.g. `--dir=~/My\ Music` – Steve Barnes Apr 09 '14 at 12:06
  • Are you trying to make sure the arguments are in the correct format? Only checking if quotes surround the argument will not cover all cases, as @SteveBarnes has mentioned. – icedtrees Apr 09 '14 at 12:10
  • Your entire --dir parameter will be seen as a single parameter with an embedded space by both CMD and Python. Test it with a little script like: `echo {%1} {%2} {%3}` – Todd Apr 09 '14 at 12:11
  • @icedtrees I am just trying to make sure that if there was a space in the input argument and if there were spaces, that the path didn't get messed up because of it. What is happening now is that the script can't find the path if there are no quotes around it because C:\Users\heinst\Documents\heinsts doesnt exist, but C:\Users\heinst\Documents\heinsts music does – heinst Apr 09 '14 at 12:13
  • @heinst it is impossible to check if there are spaces outside quotes, or even how many spaces there are outside quotes. See http://stackoverflow.com/questions/667540/full-command-line-as-it-was-typed - it is already too late by the time the args reach your python program. Your best bet is to follow tutuDajuju's method, where a good error exit message is produced when args are incorrect, or you can do some hacky manual handling where you assume there is only one space, and " ".join the offending args. – icedtrees Apr 09 '14 at 12:45
  • Thanks @icedtrees you have been really helpful – heinst Apr 09 '14 at 12:51
  • Since args are an ordered list, parsing args with spaces is not impossible (just hard). Getting them raw and unquoted however, is really impossible (on most operating systems) – tutuDajuju Apr 09 '14 at 14:12

2 Answers2

2

You can use the standard package argparse, it will take care of parsing the string properly to include the spaces. It also lets you have many other features (like automatically prepare the command help, here's a tutorial):

(Originally taken from this question)

Edit:

I've finally got what the OP meant! Luckily argv is an ordered list so it is possible to parse the dir with spaces.

This is also possible with argparse (see updated example below, solution shamelessly stolen from this question)

The downside to passing unquoted data is that the operating system escapes special chars (like backslashes) before they are passed to the python interpreter. So your script users would have to pass dirs with double quotes (c:\\Users\\) ...

Not sure which is better but, I'd go with documenting the instructions in the opts (super easy with argparse) and in your documentation.

example.py

import argparse


class JoinAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, " ".join(values))

parser = argparse.ArgumentParser()
parser.add_argument("-copyDir", action="store_true")
parser.add_argument("-d", "--dir", nargs="+", action=JoinAction)
args = parser.parse_args()
print args.__dict__

running it

$ python example.py -copyDir --dir C:\\Users\\heinst\\Documents\\heinsts music
{'copyDir': True, 'dir': 'C:\\Users\\heinst\\Documents\\heinsts music'}
tutuDajuju
  • 10,307
  • 6
  • 65
  • 88
  • Updated to the example to include a space and clarify answer. You can now see that it takes care of parsing what's inside the double quotes into the "dir" argument – tutuDajuju Apr 09 '14 at 12:40
  • 1
    This is the best solution, but it still does not solve the poster's problem. If you read the post carefully, you will note that the poster is using argv, which already handles spaces correctly. The poster wants to handle spaces OUTSIDE quotes, when the argument format is incorrect. – icedtrees Apr 09 '14 at 12:46
1

You can simply do something like:

if your_input[0] == your_input[-1] == '"':
    #do something

where your_input is the string: "C:\Users\heinst\Documents\heinsts music"

sshashank124
  • 31,495
  • 9
  • 67
  • 76