2

I have a Perl script, which uses GetOpts long. A command like this is easily handled:

automate -action build,deploy -modules chat,email,login 

What I want to achieve is to allow the user to give spaces between arguments.

E.g

automate -action build, deploy   -modules chat, email, login

The issue is that GetOpt::Long internally uses @ARGV to set the variables as needed, and a space changes the @ARGV array, which in turn will put only 'build' as an action, and only 'chat' as a module for the script, ignoring the rest of the arguments passed.

Is there a simple way to parse a command line like the one above in Perl?

I hope there is because otherwise I will have to use a very hacky way of changing the @ARGV array before it is passed to GetOpts.

Are there any other robust libraries out there which will do this for me?

---------------------------Tailor-made script--------------------------------

GetOptions("action=s{1,4}"=>\@myactions,
            "modules=s{,}"=>\@mymodules);

foreach(@mymodules)
{
      if($_ eq $mymodules[0])
      {
          $mymodules= $mymodules.$_;
          next;
      }
      if($dashboards =~ m/,$/ || $_ =~ m/^,/)
      {
          $mymodules= $mymodules.$_;
      }
      else
      {
          $mymodules= $mymodules.",".$_;
      }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Neeraj
  • 8,408
  • 8
  • 41
  • 69
  • 1
    this is not a good idea - having space-separated argument lists is contrary to most CLI UI standards. You should never deviate from what most users are familiar with when designing UIs (command line ones included) without a very good reason – DVK Apr 13 '11 at 20:21
  • Note that you can normalize `@ARGV` any way that you like before you call GetOptions. But, this is a very bad idea since people will not expect to this sort of interface. – brian d foy Apr 01 '21 at 11:45

2 Answers2

4

Check out this Options with multiple values section in the Getopt::Long perldoc. It appears similar to what you're looking for.

Example:

    GetOptions ("action=s{,}" => \@valuelist);
    @values = split(/[\s,]+/,join(',' , @valuelist));

    # @values will contain the list of values passed to the option.
    # This can handle the scenarios:
    # <command> -action build,deploy
    # <command> -action build, deploy
    # <command> -action build deploy
Shalini
  • 455
  • 1
  • 3
  • 5
  • Yes checked that out already.That will only allow me stuff seperated with white spaces, commas will not form a part of the argument by default... Nonetheless, ive come up with my own script to get that stuff done, please let me know if there are any pitfalls in that.. that would be a great help.I will update my question in sometime. – Neeraj Apr 13 '11 at 08:57
  • @Neeraj - Yes, you are right. The default is to have the multiple values separated by spaces. But, if you choose to use a delimiter, can't you split to get the list of values passed ? I have upated my answer with the solution I had in mind, just in case ... – Shalini Apr 13 '11 at 16:29
  • The answer you have posted, I had already implemented in the code.But only a more finer,enhanced version.I have added the script in the answer.The script will even allow, stuff like --action deploy , package.The script you have posted, this will end up with a wrong values string, as 'deploy' ',' 'package' will be taken as three different arguments. – Neeraj Apr 14 '11 at 06:21
1

That's a non-standard command line usage - so you'll need a non-standard command line parser. There are about 180 separate entries listed if you do a search for 'getopt' at http://search.cpan.org/, so there are many to choose from.

Superficially, you simply want to recognize some long option names, and then keep applying non-option arguments to the previous option name as they're read.

Would you insist on trailing commas? It feels clunky to do so. I can see:

automate -action build deploy -modules chat email login

Requiring commas at the end of some arguments would feel - weird.

You'd need to consider whether a double-dash option has special significance, and whether a single dash option has special significance:

somecmd -f - --

I don't know of a Perl module that handles your chosen notation, or any of the minor variations on it. That isn't quite the same as saying there is no such module, but you are attempting a slightly unusual argument parsing style, so it is quite likely that no-one has implemented exactly what you want.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Note that with the notation `automate -action build, deploy -modules chat, email, login`, the shell is responsible for passing 8 arguments to the `automate` script; with the notation `automate -action build,deploy -modules chat,email,login`, the shell passes just 5 arguments. You could probably use `automate -action "build, deploy" -modules "chat, email, login"` on the command line; at least you'll only get 5 arguments to the script, and you can split the arguments containing spaces. I stand by the observation that the desired usage is unusual and generally not supported. – Jonathan Leffler Mar 31 '21 at 18:21