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


In reply to Re: Scalar to @ARGV for Getopt::Std by haukex
in thread Scalar to @ARGV for Getopt::Std by c64whiz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.