in reply to Scalar to @ARGV for Getopt::Std
Hi c64whiz,
Some shells have ludicrously complex quoting/interpolation rules, so personally I'd avoid trying to re-implement them. If you really wanted to implement a simple subset of them though, there's Text::ParseWords, this is what Getopt::Long's GetOptionsFromString uses.
But I have the same question afoken already asked: why are you getting the command line on STDIN?
Here is a possible solution for applying getopts to a string:
use warnings; use strict; =head2 getopts_from_str(string, argumentspec, hashref) This function uses L<Text::ParseWords>'s C<shellwords> to parse the given I<string>, and then applies C<getopts> from L<Getopt::Std> to the result, passing it the I<argumentspec> and I<hashref>. If C<getopts> returns a true value, this function returns an arrayref of the arguments remaining after applying C<getopts>, and if C<getopts> reports an error by returning false, this function also returns false. =cut use Text::ParseWords 'shellwords'; use Getopt::Std 'getopts'; sub getopts_from_str { my ($str,$argspec,$hashref) = @_; local @ARGV = shellwords($str); return unless getopts($argspec, $hashref); return [@ARGV]; } # Example Code: my $optstr = q{ -a "hello world" -b "some \"text\"" -c 'abc def' }; my $argv = getopts_from_str($optstr, 'a:b:c', \my %opts) or die "bad options"; use Data::Dumper; print Dumper(\%opts, $argv); __END__ $VAR1 = { 'b' => 'some "text"', 'a' => 'hello world', 'c' => 1 }; $VAR2 = [ 'abc def' ];
Update 2016-12-20: Since I've linked to this node a few times, I updated the above code so that it provides the function getopts_from_str. The original code follows.
Anyway, this seems to work:
use warnings; use strict; use Data::Dump 'pp'; use Text::ParseWords 'shellwords'; use Getopt::Std 'getopts'; my $stdin = q{ -a "hello world" -b "some \"text\"" -c 'abc def' }; my %opts; { # for local; avoid messing with global @ARGV local @ARGV = shellwords($stdin); pp \@ARGV; getopts('a:b:c', \%opts) or die "bad options"; pp \%opts, \@ARGV; } __END__ ["-a", "hello world", "-b", "some \"text\"", "-c", "abc def"] ( { a => "hello world", b => "some \"text\"", c => 1 }, ["abc def"], )
Hope this helps,
-- Hauke D
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Scalar to @ARGV for Getopt::Std
by oiskuu (Hermit) on May 21, 2016 at 00:51 UTC |