Trouble with @ARGV

F

ff0000

Hi,

I'm in trouble and doubt (is it a Perl or shell (Bash) fault? :)
while understanding the
@ARGV behaviour... Here's a simple (newbie) script:

--
#!/usr/bin/perl

print "ARGV: `" . "@ARGV" . "`\n";

for my $i (0..$#ARGV) {
print "Argument[${i}]: `" . $ARGV[$i] . "`\n";

}

1;
--

First case:

ff0000@tsi00588pc:tmp$ ./test.pl "a b c"
ARGV: `a b c`
Argument[0]: `a b c`

The "a b c" quoting has been eating up; ok let's protect it:

ff0000@tsi00588pc:tmp$ ./test.pl \"a b c\"
ARGV: `"a b c"`
Argument[0]: `"a`
Argument[1]: `b`
Argument[2]: `c"`

Ouch! The protection has splitted the string... :-/...
Is there a way (without using extra modules) to preserve quoting
through
@ARGV?

Thanks a lot.
ff0000
 
P

Peter Makholm

ff0000 said:
I'm in trouble and doubt (is it a Perl or shell (Bash) fault? :)

It is you shell that parses the command line and places it it @ARGV,
so you question is a bash question and not really a perl question.

This would work:

ff0000@tsi00588pc:tmp$ ./test.pl '"a b c"'

//Makholm

note)
well, the shell places the parsed arguments in the C equivalent
of @ARGV and whatever perl doesn't uses itself it places in @ARGV.
 
F

ff0000

Hi Makholm,

Thanks for gonna be so fast :)
This would work:
ff0000@tsi00588pc:tmp$ ./test.pl '"a b c"'
Yes, this works nice...
So, I expand the question: if I want to parse a command line like
this:

$ perl_script.pl --option=value_1,value_2="a simple string, for
value_2"

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Do you think it's impossible to preserve the above marked quoting?
I mean "preserve it" without double quoting it or change somewhat
relative
to current shell setting (i don't want to force user habits :)...

Bye.
ff0000
 
M

Matija Papec

ff0000 said:
Yes, this works nice...
So, I expand the question: if I want to parse a command line like
this:

$ perl_script.pl --option=value_1,value_2="a simple string, for
value_2"

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Do you think it's impossible to preserve the above marked quoting?
I mean "preserve it" without double quoting it or change somewhat
relative
to current shell setting (i don't want to force user habits :)...

Perhaps you could look at @ARGV as a string, and set your own parsing rules.


my $aline = "@ARGV";
# ..
# remove leading "--", etc.

my %opt = map { split /=/ } split /,/, $aline;

use Data::Dumper;
print Dumper \%opt;
 
F

ff0000

Hi,
Perhaps you could look at @ARGV as a string, and set your own parsing rules.

my $aline = "@ARGV";
# ..
# remove leading "--", etc.

my %opt = map { split /=/ } split /,/, $aline;

use Data::Dumper;
print Dumper \%opt;
I can't split in such way, because i invoke this:

$ perl_script.pl --option=value_1,value_2="a simple, string"

but to perl arrive this @ARGV:

--option=value_1,value_2=a simple, string

and your dump isn't pretty good:

$ ./test.pl --option=value_1,value_2="a simple, string"

$VAR1 = {
' string' => undef,
'value_2' => 'a simple',
'--option' => 'value_1'
};

:-|... Maybe i could avoid this mess (and take me to an easy
parsing) using a space separator instead of ','...

Thank you all! :)
ff0000
 
F

ff0000

Hi,
Perhaps you could look at @ARGV as a string, and set your own parsing rules.

my $aline = "@ARGV";
# ..
# remove leading "--", etc.

my %opt = map { split /=/ } split /,/, $aline;

use Data::Dumper;
print Dumper \%opt;
I can't split in such way, because i invoke this:

$ perl_script.pl --option=value_1,value_2="a simple, string"

but to perl arrive this @ARGV:

--option=value_1,value_2=a simple, string

and your dump isn't pretty good:

$ ./test.pl --option=value_1,value_2="a simple, string"

$VAR1 = {
' string' => undef,
'value_2' => 'a simple',
'--option' => 'value_1'
};

:-|... Maybe i could avoid this mess (and take me to an easy
parsing) using a space separator instead of ','...

Thank you all! :)
ff0000
 
F

ff0000

Hi,
Perhaps you could look at @ARGV as a string, and set your own parsing rules.

my $aline = "@ARGV";
# ..
# remove leading "--", etc.

my %opt = map { split /=/ } split /,/, $aline;

use Data::Dumper;
print Dumper \%opt;
I can't split in such way, because i invoke this:

$ perl_script.pl --option=value_1,value_2="a simple, string"

but to perl arrive this @ARGV:

--option=value_1,value_2=a simple, string

and your dump isn't pretty good:

$ ./test.pl --option=value_1,value_2="a simple, string"

$VAR1 = {
' string' => undef,
'value_2' => 'a simple',
'--option' => 'value_1'
};

:-|... Maybe i could avoid this mess (and take me to an easy
parsing) using a space separator instead of ','...

Thank you all! :)
ff0000
 
F

ff0000

Hi,
Perhaps you could look at @ARGV as a string, and set your own parsing rules.

my $aline = "@ARGV";
# ..
# remove leading "--", etc.

my %opt = map { split /=/ } split /,/, $aline;

use Data::Dumper;
print Dumper \%opt;
I can't split in such way, because i invoke this:

$ perl_script.pl --option=value_1,value_2="a simple, string"

but to perl arrive this @ARGV:

--option=value_1,value_2=a simple, string

and your dump isn't pretty good:

$ ./test.pl --option=value_1,value_2="a simple, string"

$VAR1 = {
' string' => undef,
'value_2' => 'a simple',
'--option' => 'value_1'
};

:-|... Maybe i could avoid this mess (and take me to an easy
parsing) using a space separator instead of ','...

Thank you all! :)
ff0000
 
R

Ron Bergin

Hi,





I can't split in such way, because i invoke this:

$ perl_script.pl --option=value_1,value_2="a simple, string"

but to perl arrive this @ARGV:

--option=value_1,value_2=a simple, string

and your dump isn't pretty good:

$ ./test.pl --option=value_1,value_2="a simple, string"

$VAR1 = {
' string' => undef,
'value_2' => 'a simple',
'--option' => 'value_1'
};

:-|... Maybe i could avoid this mess (and take me to an easy
parsing) using a space separator instead of ','...

Thank you all! :)
ff0000

Personally, I'd use a module that is designed for retrieving command
line options.

Getopt::Long
http://search.cpan.org/~jv/Getopt-Long-2.37/lib/Getopt/Long.pm

Getopt::Simple
http://search.cpan.org/~rsavage/Getopt-Simple-1.49/lib/Getopt/Simple.pm
 
F

ff0000

Hi Ron,
Personally, I'd use a module that is designed for retrieving command
line options.
Getopt::Longhttp://search.cpan.org/~jv/Getopt-Long-2.37/lib/Getopt/Long.pm
Getopt::Simplehttp://search.cpan.org/~rsavage/Getopt-Simple-1.49/lib/Getopt/Simple.pm
Yes, i know them, but i try to avoid extra modules in order to have a
script that
runs with a standard Perl installation...
However Getopt::Simple seems really too simple, while Getopt::Long
lacks some features
i need (more powerfull callback usage per option, number of value per
options, ...).

That's all! :)

See you and thank you again.
ff0000
 
R

Ron Bergin

Hi Ron,


Yes, i know them, but i try to avoid extra modules in order to have a
script that
runs with a standard Perl installation...

That's a very short sided and IMO a bad guideline to follow.

BTW, both of those are core modules, so they do come with the standard
Perl installation.
http://perldoc.perl.org/index-modules-G.html
However Getopt::Simple seems really too simple, while Getopt::Long
lacks some features

What features do you feel it lacks?

Getopt::Simple is a wrapper for Getopt::long which provides a simple
interface. Are you saying that you don't like to use clean/simple
approaches that do the job well?
i need (more powerfull callback usage per option, number of value per
options, ...).

You can write your own callbacks sub that do anything you want, so how
is that not powerful enough?
 
F

ff0000

Hi again :),
I do not know what you mean by "callback usage per option" or "number
of value per options".
Oh, my damned bad english... Sorry, I'll try to explain in a better
way.
First of all i don't use any modules because i'm learning Perl and i
want,
for example, writing my own debugging module, options parsing
module, ...
(when i'll achieve a good point, i'll move into modules' world to
compare
and surely improve my code).
You could think i'm fool... Mmmmh... So i am :)...
Your original example was parsing multiple
values of a single option, e.g. --opt=value1,value2,value3.
Getopt::Long can handle this in two ways. Firstly, as shown above and
then parsed with split:

GetOptions( "opt=s" => \$opt );
@args = split(/,/,$opt);

and used thusly:

test.pl --opt=value1,value2,value3

Secondly by putting any number of option values into an array:

my @args;
GetOptions( "opt=s" => \@args );

and called thusly:

test.pl --opt=value1 --opt=value2 --opt=value3
I see these features yet.
Perhaps if you are more clear about what it is that you are trying to
accomplish, someone can recommend alternative ways to do it.
Our code handles options' features such min and max arguments per
options
and options' description (for automatic help building).
So it's a bit difficult to merge Getopt::Long with our features.
I hope i give you a better explanation this time.

Bye and thanks.
ff0000
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top