Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Parsing Command Line Options

by mmartin (Monk)
on Jan 12, 2012 at 20:35 UTC ( [id://947635]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks,

I've been googling the heck out of this but couldn't find anything about it. If anyone will know I know you guys will.

So in my script I'm using the Getopt::Long module.
If for example, I have the following command line command (below):

$ ./my_script.pl --opt1=test1 --cfg=test 2 --location=fake file name

Is there a way to specifiy that "If any $ARGVs are found AFTER the '--cfg=' option then add those to the specified cfg filename separated by a '-' or '_'..."
I used the below code to sort of do what I wanted, but if the options aren't in a specific order it won't work correct. I want to be able to make sure users don't mess that up when executing by putting spaces in the filename.


This code below sort of does what I want, but if say a random word is before/after any other arguments it adds them to the cfg filename as well.

Executing Command with:
./my_script --cfg=my test 2.cfg --location=fake location name
####START CODE my $location; my $user_cfg; #Define argument types GetOptions('location=s' => \$location, 'cfg=s' => \$user_cfg); # Process Command Line Arguments if ( @ARGV > 0 ) { #Check if cfg option was specified if ($user_cfg) { #Replace any spaces found in a "quoted" filename #i.e. ("sample test" --> "sample-test") if ($user_cfg =~ /\s/) { $user_cfg =~ s/\s+/-/g; } if (@ARGV) { foreach my $opt (@ARGV) { $user_cfg .= "-$opt"; } } } } print "location = $location\n"; print "cfg File = $user_cfg\n"; ### END CODE

______ACTUAL OUTPUT______

location = fake
cfg File = my-test-2.cfg-location-name

This is what I would want:
my-test-2.cfg

If that really isn't possible, is there some kind of global variable (like $?, $!, etc...) that holds that entire line just executed through the command line (i.e. a variable that has this as it's value "./my_script --cfg=my test 2.cfg --location=fake location name")...? If there is a variable such as that then I could just parse it myself.


Any suggestions would be great.


Thanks in Advance,
Matt


Replies are listed 'Best First'.
Re: Parsing Command Line Options
by toolic (Bishop) on Jan 12, 2012 at 20:45 UTC
    I think you want to just quote your values in your shell:
    use warnings; use strict; use Getopt::Long; my $location; my $user_cfg; #Define argument types GetOptions('location=s' => \$location, 'cfg=s' => \$user_cfg); #Check if cfg option was specified if ($user_cfg) { #Replace any spaces found in a "quoted" filename #i.e. ("sample test" --> "sample-test") $user_cfg =~ s/\s+/-/g; } print "location = $location\n"; print "cfg File = $user_cfg\n"; __END__ $ ./my_script --cfg='my test 2.cfg' --location='fake location name' location = fake location name cfg File = my-test-2.cfg
    is there some kind of global variable (like $?, $!, etc...) that holds that entire line just executed through the command line
    $0 stores the command name and @ARGV stores all the arguments. Getopt::Long parses @ARGV.
      toolic,

      Sorry I didn't see the 2nd half of your reply about the $0 and ARGV stuff...

      Sweet, I'll give that a try. But it sounds like that's what I'm looking for.


      Thanks Again,
      Matt


      Hey toolic, thanks for the reply.

      Right, if they quote it it would not be a problem. But some people using this may not be the most computer savvy people, and I want to just make sure they can't screw it up.


      Thanks,
      Matt

        If they're not that savvy, tell them to stop using spaces in their filenames ;-)

        There really is no straight-forward, simple, and portable answer to your question, short of some minor retraining of your users. For example, if I specify "--cfg=my  cfg" with two spaces, there's basically no way to recover that - the shell will eat the spaces. (Some shells may save the original command in an environment variable, but, again, it's not portable, and may not apply to your shell/OS/users.) You could, I suppose, use *'s instead of -'s or _'s and the glob function, but at some point you're getting far too smart and will likely end up getting in trouble.

        If you continue to try, you may have to pre-process @ARGV, merging any argument that doesn't start with a dash in with the previous argument. But, even then, it gets annoying, really fast.

        Also, your interface will be completely non-standard. Users learning your way of doing things will not be able to apply that knowledge to any other application. However, if you teach them the "normal" way (quoting, or just putting in the dashes if that's what they want to use), that knowledge and experience will then transfer to any other program they use.

        Sounds like what you really need is a GUI interface for users who can't handle the command line :-) (And lest that sound condescending, it's not intended to - presumably those users are providing other value to their employer to justify their salary which would be more valuable than another command-line expert :-) )

Re: Parsing Command Line Options
by mmartin (Monk) on Jan 12, 2012 at 21:18 UTC
    Hey Guys, thanks for your help.

    I guess I'll just take Tanktalus' suggestion and smack the user around a bit lol...


    Thanks Again,
    Matt


Re: Parsing Command Line Options
by mmartin (Monk) on Jan 12, 2012 at 21:20 UTC
    One more thing before I go..


    Does anyone have a link to a site that lists all the Global Variables available to Perl?


    Thanks,
    Matt

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://947635]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-03-19 11:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found