For Programmers: Free Programming Magazines  


Home > Archive > PERL Modules > October 2006 > Is this bug in Getopt::Std?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Is this bug in Getopt::Std?
Hemant Shah

2006-10-20, 6:56 pm

Folks,

Here is the sample perl script:


#!/usr/bin/perl

use Getopt::Std;

my %Options;

getopts('C:', \%Options);

print "Comment = $Options{C}\n";
print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);




When I run the script as follows:

../tstgetopts.pl -a"Comment"
Unknown option: a
Comment = omment



Why does getopts set value for $Options{C}?
It should be a left in %ARGV.

If I use space in between then it works as expected.

../tstgetopts.pl -a "Comment"
Unknown option: a
Comment =
ARGV[0] = Comment


Is this a bug or am I missing something?




--
Hemant Shah /"\ ASCII ribbon campaign
E-mail: NoJunkMailshah@xnet.com \ / ---------------------
X against HTML mail
TO REPLY, REMOVE NoJunkMail / \ and postings
FROM MY E-MAIL ADDRESS.
-----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
I haven't lost my mind, Above opinions are mine only.
it's backed up on tape somewhere. Others can have their own.
Paul Lalli

2006-10-20, 6:56 pm

Hemant Shah wrote:
> Here is the sample perl script:
>
>
> #!/usr/bin/perl
>
> use Getopt::Std;
>
> my %Options;
>
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);


>
> When I run the script as follows:
>
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
> Why does getopts set value for $Options{C}?
> It should be a left in %ARGV.
>
> If I use space in between then it works as expected.
>
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =
> ARGV[0] = Comment
>
> Is this a bug or am I missing something?


You're missing something.

Quotes are not a shell argument separator. This has nothing to do with
Perl, btw. Saying
../tstgetopts.pl -a"Comment"
is exactly the same as
../tstgetopts.pl -aComment

Getopts assumes that one switch is a cluster of single switches, until
it gets to C, which takes a value....

Take a look at this example, and see if that helps you understand:
perl -le'print for @ARGV' foo bar foo "bar" foo"bar"
foo
bar
foo
bar
foobar


Hope this helps,
Paul Lalli

Joe Smith

2006-10-21, 3:56 am

Hemant Shah wrote:

> getopts('C:', \%Options);


The example given in 'perldoc Getopt::Std' has
getopts('oif:'); # -o & -i are boolean flags, -f takes an argument

That means it would accept
-o -i -fFile
and
-oi -f File
and
-oifFile
since getopts allows option bundling. Individual option letters can
be specified each with its own hyphen, or several of the letters
can be bunched up together behind a single hyphen.

> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment


Those double quotes make no difference when specified to a Unix
shell. What you typed is the same as
./tstgetopts.pl -aComment
and is interpreted as
./tstgetopts.pl -a -Comment
which has an unknown option "-a" and "-C" with argument "omment".

> Is this a bug or am I missing something?


I'd say it is a problem with the documentation.
-Joe
Dr.Ruud

2006-10-21, 7:56 am

Joe Smith schreef:

> ./tstgetopts.pl -aComment
> and is interpreted as
> ./tstgetopts.pl -a -Comment


And further as "./tstgetopts.pl -a -C -o -m -m -e -n -t":

#!/usr/bin/perl
use strict ;
use warnings ;

use Getopt::Std ;

my %opts ;

{ local ($\, $", $,) = ("\n", '', "\t") ;

getopts("@{['a'..'z', 'A'..'Z']}", \%opts) ;

print $_, $opts{$_} for (sort keys %opts) ;
}
__END__

$ perl test.pl -a"Comments"
C 1
a 1
e 1
m 1
n 1
o 1
s 1
t 1

$ perl test.pl -a "Comments"
a 1

--
Affijn, Ruud

"Gewoon is een tijger."
anno4000@radom.zrz.tu-berlin.de

2006-10-22, 3:57 am

Hemant Shah <NoJunkMailshah@xnet.com> wrote in comp.lang.perl.misc:
> Folks,
>
> Here is the sample perl script:
>
>
> #!/usr/bin/perl
>
> use Getopt::Std;
>
> my %Options;
>
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
>
>
>
>
> When I run the script as follows:
>
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
>
>
> Why does getopts set value for $Options{C}?
> It should be a left in %ARGV.
>
> If I use space in between then it works as expected.
>
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =
> ARGV[0] = Comment
>
>
> Is this a bug or am I missing something?


What version of Getopt::Std are you using? 1.05 works as expected:

Unknown option: a
Use of uninitialized value in concatenation (.) or string at ./ttt line 10.
Comment =

Anno
Martijn Lievaart

2006-10-22, 7:57 am

On Fri, 20 Oct 2006 19:00:55 +0000, Hemant Shah wrote:

> Folks,
>
> Here is the sample perl script:
>
>
> #!/usr/bin/perl
>
> use Getopt::Std;
>
> my %Options;
>
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
>
>
>
>
> When I run the script as follows:
>
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
> Is this a bug or am I missing something?


Excactly what one would expect inder most shells.

-a"Comment" gets dequoted so becomes -aComment. -a is unknown, so it is
assumed to take no value. Processing continues with the second switch,
which is a "C".

M4
--
Redundancy is a great way to introduce more single points of failure.

Brian McCauley

2006-10-22, 6:56 pm


Hemant Shah wrote:
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);


> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
>
>
> Why does getopts set value for $Options{C}?


Because it has to either treat the -a switch as valued or unvalued and
it happens to treat it as unvalued.

> It should be a left in %ARGV.


What is %ARGV?

> If I use space in between then it works as expected.
>
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =
> ARGV[0] = Comment
>
>
> Is this a bug


No.

> or am I missing something?


Perhaps you are missing that if -a is an unvalued switch then

-aComment

is the same as

-a -Comment

Dan Mercer

2006-10-22, 6:56 pm


"Hemant Shah" <shah@typhoon.xnet.com> wrote in message news:ehb6d7$qd4$1@new7.xnet.com...
: Folks,
:
: Here is the sample perl script:
:
:
: #!/usr/bin/perl
:
: use Getopt::Std;
:
: my %Options;
:
: getopts('C:', \%Options);
:
: print "Comment = $Options{C}\n";
: print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
:
:
:
:
: When I run the script as follows:
:
: ./tstgetopts.pl -a"Comment"
: Unknown option: a
: Comment = omment
:
:
:
: Why does getopts set value for $Options{C}?
: It should be a left in %ARGV.
:
: If I use space in between then it works as expected.
:
: ./tstgetopts.pl -a "Comment"
: Unknown option: a
: Comment =
: ARGV[0] = Comment
:
:
: Is this a bug or am I missing something?

You are missing something.

cmd -a -b -c

Can also be specified as

cmd -abc

and

cmd -a -B value

can be represented as

cmd -aBvalue

Running into an unrecognized option it treats that as a flag option
and keeps interpreting. So the C is recognized as a parameter option
and omment as the parameter.

Dan Mercer

:
:
:
:
: --
: Hemant Shah /"\ ASCII ribbon campaign
: E-mail: NoJunkMailshah@xnet.com \ / ---------------------
: X against HTML mail
: TO REPLY, REMOVE NoJunkMail / \ and postings
: FROM MY E-MAIL ADDRESS.
: -----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
: I haven't lost my mind, Above opinions are mine only.
: it's backed up on tape somewhere. Others can have their own.


Hemant Shah

2006-10-22, 9:56 pm

While stranded on information super highway Dan Mercer wrote:
>
> "Hemant Shah" <shah@typhoon.xnet.com> wrote in message news:ehb6d7$qd4$1@new7.xnet.com...
> : Folks,
> :
> : Here is the sample perl script:
> :
> :
> : #!/usr/bin/perl
> :
> : use Getopt::Std;
> :
> : my %Options;
> :
> : getopts('C:', \%Options);
> :
> : print "Comment = $Options{C}\n";
> : print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
> :
> :
> :
> :
> : When I run the script as follows:
> :
> : ./tstgetopts.pl -a"Comment"
> : Unknown option: a
> : Comment = omment
> :
> :
> :
> : Why does getopts set value for $Options{C}?
> : It should be a left in %ARGV.
> :
> : If I use space in between then it works as expected.
> :
> : ./tstgetopts.pl -a "Comment"
> : Unknown option: a
> : Comment =
> : ARGV[0] = Comment
> :
> :
> : Is this a bug or am I missing something?
>
> You are missing something.
>
> cmd -a -b -c
>
> Can also be specified as
>
> cmd -abc
>


I understand that, but if the next character is a quote it should not be
igmored.

cmd -ab"c"

Why does it consider as an option?

> and
>
> cmd -a -B value
>
> can be represented as
>
> cmd -aBvalue
>
> Running into an unrecognized option it treats that as a flag option
> and keeps interpreting. So the C is recognized as a parameter option
> and omment as the parameter.
>
> Dan Mercer
>
> :
> :
> :
> :
> : --
> : Hemant Shah /"\ ASCII ribbon campaign
> : E-mail: NoJunkMailshah@xnet.com \ / ---------------------
> : X against HTML mail
> : TO REPLY, REMOVE NoJunkMail / \ and postings
> : FROM MY E-MAIL ADDRESS.
> : -----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
> : I haven't lost my mind, Above opinions are mine only.
> : it's backed up on tape somewhere. Others can have their own.
>
>


--
Hemant Shah /"\ ASCII ribbon campaign
E-mail: NoJunkMailshah@xnet.com \ / ---------------------
X against HTML mail
TO REPLY, REMOVE NoJunkMail / \ and postings
FROM MY E-MAIL ADDRESS.
-----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
I haven't lost my mind, Above opinions are mine only.
it's backed up on tape somewhere. Others can have their own.
Hemant Shah

2006-10-22, 9:56 pm

While stranded on information super highway Brian McCauley wrote:
>
> Hemant Shah wrote:
>
>
> Because it has to either treat the -a switch as valued or unvalued and
> it happens to treat it as unvalued.


"a" is an invalid option, if it finds a quote then it should stop processing
it as an option.

>
>
> What is %ARGV?
>
>
> No.
>
>
> Perhaps you are missing that if -a is an unvalued switch then
>
> -aComment
>
> is the same as
>
> -a -Comment
>


--
Hemant Shah /"\ ASCII ribbon campaign
E-mail: NoJunkMailshah@xnet.com \ / ---------------------
X against HTML mail
TO REPLY, REMOVE NoJunkMail / \ and postings
FROM MY E-MAIL ADDRESS.
-----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
I haven't lost my mind, Above opinions are mine only.
it's backed up on tape somewhere. Others can have their own.
Hemant Shah

2006-10-22, 9:56 pm

While stranded on information super highway anno4000@radom.zrz.tu-berlin.de wrote:
> Hemant Shah <NoJunkMailshah@xnet.com> wrote in comp.lang.perl.misc:
>
> What version of Getopt::Std are you using? 1.05 works as expected:
>
> Unknown option: a
> Use of uninitialized value in concatenation (.) or string at ./ttt line 10.
> Comment =
>


I am using Getopt 1.05. Here is the version from Std.pm

@ISA = qw(Exporter);
@EXPORT = qw(getopt getopts);
$VERSION = '1.05';
# uncomment the next line to disable 1.03-backward compatibility paranoia
# $STANDARD_HELP_VERSION = 1;



> Anno


--
Hemant Shah /"\ ASCII ribbon campaign
E-mail: NoJunkMailshah@xnet.com \ / ---------------------
X against HTML mail
TO REPLY, REMOVE NoJunkMail / \ and postings
FROM MY E-MAIL ADDRESS.
-----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
I haven't lost my mind, Above opinions are mine only.
it's backed up on tape somewhere. Others can have their own.
Ferry Bolhar

2006-10-23, 3:57 am

Hermant Shah:

> Why does getopts set value for $Options{C}?
> It should be a left in %ARGV.


No, why? The invalid -a option is ignored (and causes a
warning to be printed). Then further option processing
will occur with -C. And because this a valid option which
takes a value, the value is store in the %options hash and
is removed from %ARGV.

You should note that the quotes are removed by the shell
before the command line is passed to perl. So getopts sees
the string

-aComment

> If I use space in between then it works as expected.


Of course, because -a is ignored and so the next argument
without a leading dash becomes the first argument.

> Is this a bug or am I missing something?


The latter. This is all well-documented, well-known
behaviour.

Greetings, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at


Dr.Ruud

2006-10-23, 3:57 am

Hemant Shah schreef:

> "a" is an invalid option, if it finds a quote then it should stop
> processing it as an option.


But does "it" find a quote?

$ perl -MData::Dumper -wle 'print Dumper \@ARGV' -- -a"Command"
$VAR1 = [
'-aCommand'
];



$ perl -MData::Dumper -wle 'print Dumper \@ARGV' -- -a "Command"
$VAR1 = [
'-a',
'Command'
];

--
Affijn, Ruud

"Gewoon is een tijger."
Josef Moellers

2006-10-23, 3:57 am

Hemant Shah wrote:
> Folks,
>=20
> Here is the sample perl script:
>=20
>=20
> #!/usr/bin/perl
>=20
> use Getopt::Std;
>=20
> my %Options;
>=20
> getopts('C:', \%Options);
>=20
> print "Comment =3D $Options{C}\n";
> print "ARGV[0] =3D $ARGV[0]\n" if ($ARGV[0]);
>=20
>=20
>=20
>=20
> When I run the script as follows:
>=20
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment =3D omment
>=20
>=20
>=20
> Why does getopts set value for $Options{C}?=20
> It should be a left in %ARGV.
>=20
> If I use space in between then it works as expected.
>=20
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =3D=20
> ARGV[0] =3D Comment
>=20
>=20
> Is this a bug or am I missing something?


From "man Getopt::Std":
"The getopt() function processes single-character switches with switch=20
clustering."

This means, that '-a"Comment"' is first treated as '-aComment' which is=20
then treated as '-a -Comment', in absence of a specification of the=20
'a'-option.
Getopt::Std treats '-a' as an option which does not take an argument.=20
Hence the '-Comment' which will then be processed according to the=20
'C:'-specification.

'-a Comment', however, is treated as '-a Comment'. The '-a' is treated=20
as above, the 'Comment' is then left over as a command line argument.

--=20
Josef M=F6llers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett

Hemant Shah

2006-10-23, 6:57 pm


Thanks to everyone who replied. I should have realized that the shell is to
blame for it. I strips of quotes before passing the aprameters to perl.


In comp.lang.perl.modules Hemant Shah <shah@typhoon.xnet.com> wrote:
> Folks,
>
> Here is the sample perl script:
>
>
> #!/usr/bin/perl
>
> use Getopt::Std;
>
> my %Options;
>
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
>
>
>
>
> When I run the script as follows:
>
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
>
>
> Why does getopts set value for $Options{C}?
> It should be a left in %ARGV.
>
> If I use space in between then it works as expected.
>
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =
> ARGV[0] = Comment
>
>
> Is this a bug or am I missing something?
>
>
>
>
> --
> Hemant Shah /"\ ASCII ribbon campaign
> E-mail: NoJunkMailshah@xnet.com \ / ---------------------
> X against HTML mail
> TO REPLY, REMOVE NoJunkMail / \ and postings
> FROM MY E-MAIL ADDRESS.
> -----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
> I haven't lost my mind, Above opinions are mine only.
> it's backed up on tape somewhere. Others can have their own.


--
Hemant Shah /"\ ASCII ribbon campaign
E-mail: NoJunkMailshah@xnet.com \ / ---------------------
X against HTML mail
TO REPLY, REMOVE NoJunkMail / \ and postings
FROM MY E-MAIL ADDRESS.
-----------------[DO NOT SEND UNSOLICITED BULK E-MAIL]------------------
I haven't lost my mind, Above opinions are mine only.
it's backed up on tape somewhere. Others can have their own.
harryfmudd [AT] comcast [DOT] net

2006-10-23, 6:57 pm

Hemant Shah wrote:
> Folks,
>
> Here is the sample perl script:
>
>
> #!/usr/bin/perl
>
> use Getopt::Std;
>
> my %Options;
>
> getopts('C:', \%Options);
>
> print "Comment = $Options{C}\n";
> print "ARGV[0] = $ARGV[0]\n" if ($ARGV[0]);
>
>
>
>
> When I run the script as follows:
>
> ./tstgetopts.pl -a"Comment"
> Unknown option: a
> Comment = omment
>
>
>
> Why does getopts set value for $Options{C}?
> It should be a left in %ARGV.
>
> If I use space in between then it works as expected.
>
> ./tstgetopts.pl -a "Comment"
> Unknown option: a
> Comment =
> ARGV[0] = Comment
>
>
> Is this a bug or am I missing something?
>
>
>
>


It's not a bug if the documentation says it works that way. You may not
like the way it works, but it's still not a bug.

Are you required to use Getopt::Std? If you use Getopt::Long, you can
get a status back, and do something like

#!/usr/local/bin/perl

use Getopt::Long;

my %Options;

GetOptions (\%Options, qw{C=s}) or die <<eod;
The only legal option is C, which takes a string argument.
eod
print "-C = $Options{C}\n";

__END__

Note two differences in the use of Getopt::Long versus Getopt::Std:

First, you can't merge options. That is, even if -a and -C were legal
options, -aC would not be interpreted as -a -C.

Second, Getopt::Long requires some sort of punctuation between the
option name and the argument, so if your script name were 'foo', you
would invoke it as

perl foo -C omment

or as

perl foo -C=omment

but not as

perl foo -Comment

which Getopt::Std allows.

Tom Wyant
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com