hotshot has asked for the wisdom of the Perl Monks concerning the following question:

hi guys !

Im using Getopt::Long module for parsing command line arguments. the problem is when I need to enter (from the command prompt) an option value that has one or more spaces in it, for example:
--> myprog -s 'argument with space in it' # I wish that worked
in the above example I need -s option to receive a string (including spaces) in it. the problem is that the module is parsing by spaces (AFAIN) and no quotes will help, it will be parsed as a line with one option (-s with the value 'argument) and five more arguments in @ARGV. is there a way to insert a spaced argument at all?

Hotshot

Replies are listed 'Best First'.
Re: Parsing command line
by fglock (Vicar) on Aug 26, 2002 at 12:31 UTC

    Try replacing ' for ".

    From the POD:

    GetOptions does not split the command line correctly The command line is not split by GetOptions, but by the command line interpreter (CLI). On Unix, this is the shell. On Windows, it is COMMAND.COM or CMD.EXE. Other operating systems have other CLIs. It is important to know that these CLIs may behave different when the command line contains special characters, in particular quotes or backslashes. For example, with Unix shells you can use single quotes (') and double quotes (") to group words together. The following alternatives are equivalent on Unix: "two words" 'two words' two\ words In case of doubt, insert the following statement in front of your Perl program: print STDERR (join("|",@ARGV),"\n"); to verify how your CLI passes the arguments to the program.

      I tried with double quotes and it's still the same (not working of course).
      when executing:
      --> myprog -s "two words" --> myprog -s 'two words' --> myprog -s two\ words
      I got the same result: myprog|words (using the print you suggested). any ideas?

      Hotshot
Re: Parsing command line
by Tomte (Priest) on Aug 26, 2002 at 12:38 UTC

    It is nearly impossible to find an error without the code. are you sure you read perldoc Getopt::Long thouroughly?

    my $s = ''; GetOptions('string=s' => \$s);

    should normaly do what you want (it does for me). Maybe you forgot to pass your variable as a reference?


    regards,
    tomte
      I did exactly the same as you, here is it:
      local %hash; if (GetOptions(\%hash, 'pdcuse!', 'uamlist=s', 'loginmesg=s')) { &doSomething(); }
      as you can see I used hash (reference), but doesn't supposed to matter (it happened to me even when I didn't used hash).

      Hotshot
        use Getopt::Long; use strict; use warnings; use Data::Dumper; my %hash; GetOptions(\%hash, 'pdcuse!', 'uamlist=s', 'loginmesg=s'); print "" . Dumper(\%hash) . "\n"; __END__ perl test.pl -u "test eins zwei drei" -l "test drei vier fuenf" -p yields: $VAR1 = { 'pdcuse' => 1, 'uamlist' => 'test eins zwei drei', 'loginmesg' => 'test drei vier fuenf' };

        using local instead of my doesn't alter the result, it simply works...(older SuSE, bah, perl 5.6.1)
        So I'm out of luck here...
        regards,
        tomte


Re: Parsing command line
by Aristotle (Chancellor) on Aug 26, 2002 at 13:01 UTC
    That's not an issue with GetOpt::Long. The fact that you are getting 'argument with the single quote prepended means it was not interpretered by your shell. Let me go out on a limb and assume you're using a Microsoft OS. In that case you're using either COMMAND.COM or CMD.EXE which, besides being braindead, assume double rather than single quotes.

    Makeshifts last the longest.

      sorry, but i'm not using Microsoft, i'm working working on Linux.

      Hotshot
        Well, so much for that. It's still a shell issue though, not one of Perl. What shell are you using? And have you tried with double quotes?

        Makeshifts last the longest.

Re: Parsing command line
by kelan (Deacon) on Aug 26, 2002 at 17:31 UTC
    I noticed a similar issue when using Getopt::Long. Regardless of whether it's a problem with the shell or not, quoted strings don't get through intact. I wrote a simple function that takes a command line and splits it into @ARGV. You could probably modify it to work on the already-split @ARGV directly, or just do this first:
    $cmdline = join(' ',@ARGV); parsetoargv($cmdline);
    Here's the function:
    sub parsetoargv { my ($cmdline, $idx) = (shift, 0); @ARGV = (); { $cmdline =~ m{ \G\ }gcx && do {redo}; # Eat a space $cmdline =~ m{ \G" }gcx && do { # Start a quot +ed-string $cmdline =~ m{ \G(.*?)(?<!\\)" }gcx && do { # Match up t +o the next unescaped quote ($ARGV[$idx++] = $1) =~ s/\\"/"/g; # And put +it in ARGV, removing escaping slashes }; redo }; $cmdline =~ m{ \G(.*?)(?="|\ |$) }gcx && do { # Match up to +just before the next quote, space, or end-of-line $ARGV[$idx++] = $1 if ($1 ne ''); redo # And put it +in ARGV if it isn't empty }; } }
    Now your @ARGV is ready for GetOptions.