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
|
|
|
|
|