SPUG: Buggy shebang-line parsing

Tim Maher tim at consultix-inc.com
Sat Jan 15 14:20:45 PST 2005


Earlier today I posted a detailed reply to David's reply to my
message, but it has never appeared. Anyway, I've attached sample
programs that illustrate the problem to this message (one of
which has reported bug-id #30660). Enjoy!

-Tim
P.S. For the bug illustrated with -s , I'm getting the impression
that /any/ options supplied after the -F are ignored, and that
there's no problem if that option isn't present
==============================================================
| Tim Maher, Ph.D.                    tim(AT)TeachMePerl.com | 
| SPUG Leader Emeritus               spug(AT)TeachMePerl.com |
| Seattle Perl Users Group        http://www.SeattlePerl.com |
==============================================================
-------------- next part --------------
>From tim at consultix-inc.com  Fri Jul  9 09:37:30 2004

This is a bug report for perl from tim at consultix-inc.com,
generated with the help of perlbug 1.34 running under perl v5.8.2.

-----------------------------------------------------------------
[Please enter your report here]

I've either found a bug in Perl, or there's an undocumented
"feature" that I've suddenly run into for the first time.
Either way, /I don't like it/! 8-{ 

In short, a parsing rule (or bug) seems to be operating that says
after two (or more) spaces are seen on the shebang line, no
additional options are recognized! So when one tries to use -s
for switch processing, and that switch is preceded by two spaces,
the result is that the -switch=whatever argument
is /retained/ on the command line, rather than used to set a
variable! When the -w option is in the ignored position, that
fails to enable warnings.

AFAIK, this is not documented behavior, and IMHO, it is not
/desirable/ behavior.

I've included sample programs and output below, and confirmed that
the same results are obtained with Perl versions 5.8.4 and 5.8.2.

-Tim Maher
tim at teachmeperl.com

PROGRAMS:

The _sw ending on a test program means the -s option is first,
and the -w second, and vice versa. The program invocation in each
case is "./scriptname -switch", which should set the $switch
variable in the script to 1. Note that there's nothing
switch-specific about this "two-space" bug -- that's just the
context in which I originally found it, and it demonstrates the
faulty behavior well, by (erroneously) leaving the -switch
argument in @ARGV, and triggering a "possible typo" warning
regarding $switch in that case.

The two_space* versions of the programs are expected to work like
the one_space ones, but they don't.

2004-07-05 12:31                   one_space_sw                   Page 1

#! /usr/bin/perl -s -w
$switch == 1;
warn "Arguments are: @ARGV";


2004-07-05 12:31                   one_space_ws                   Page 1

#! /usr/bin/perl -w -s
$switch == 1;
warn "Arguments are: @ARGV";


2004-07-05 12:32                  two_spaces_sw                   Page 1

#! /usr/bin/perl -s  -w
$switch == 1;
warn "Arguments are: @ARGV";


2004-07-05 12:32                  two_spaces_ws                   Page 1

#! /usr/bin/perl -w  -s
$switch == 1;
warn "Arguments are: @ARGV";


OUTPUT:

RUNNING 'one_space_sw':
Useless use of numeric eq (==) in void context at ./one_space_sw line 3.
Arguments are:  at ./one_space_sw line 5.

(That's the correct result; warnings enabled, and switch-argument processed)

RUNNING 'one_space_ws':
Useless use of numeric eq (==) in void context at ./one_space_ws line 3.
Arguments are:  at ./one_space_ws line 5.

(That's the correct result; warnings enabled, and switch-argument processed)

RUNNING 'two_spaces_sw':
Arguments are:  at ./two_spaces_sw line 5.

(That's the WRONG result; warnings DISabled;
	only switch-option recognized)

RUNNING 'two_spaces_ws':
Useless use of numeric eq (==) in void context at ./two_spaces_ws line 3.
Name "main::switch" used only once: possible typo at ./two_spaces_ws line 3.
Use of uninitialized value in numeric eq (==) at ./two_spaces_ws line 3.
Arguments are: -switch at ./two_spaces_ws line 5.

(That's the WRONG result; switch not processed;
	only warning option recognized)
 
==============================================================
| Tim Maher, Ph.D.                    tim(AT)TeachMePerl.com | 
| Seattle Perl Users Group        http://www.SeattlePerl.com |
| SPUG Wiki Site               http://Spugwiki.Perlocity.org |
==============================================================


[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=medium
---
Site configuration information for perl v5.8.2:

Configured by root at Sat Nov 15 08:54:26 PST 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
  Platform:
    osname=linux, osvers=2.4.19-4gb, archname=i686-linux-thread-multi
    uname='linux jumpy 2.4.19-4gb #1 mon aug 4 23:38:42 utc 2003 i686 unknown '
    config_args='-Dusethreads'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing'
    ccversion='', gccversion='3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/ucblib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    

---
@INC for perl v5.8.2:
    /local/perl5/site_perl/5.8.2
    /usr/lib/perl5/site_perl/5.8.2
    /local/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl/5.8.0
    /local/perl5/site_perl/5.6.0
    /local/perl5/site_perl/5.005
    /local/perl5/site_perl/i386-linux
    /usr/lib/perl5/site_perl/5.8.0/i586-linux-thread-multi
    /usr/local/lib/perl5/5.8.2/i686-linux-thread-multi
    /usr/local/lib/perl5/5.8.2
    /usr/local/lib/perl5/site_perl/5.8.2/i686-linux-thread-multi
    /usr/local/lib/perl5/site_perl/5.8.2
    /usr/local/lib/perl5/site_perl
    /local/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl/5.8.0 /local/perl5/site_perl/5.6.0 /local/perl5/site_perl/i386-linux /local/perl5/site_perl/5.005
    .

---
Environment for perl v5.8.2:
    HOME=/home/tim
    LANG=en_US
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/tim/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/games:/opt/gnome2/bin:/opt/gnome/bin:/opt/kde3/bin:/opt/kde2/bin:/usr/lib/java/bin:.:/usr/X11R6/bin:/opt/kde/bin:/local/timbin:/local/dtp:/home/tim/bin:/usr/X11R6/bin:/opt/kde/bin:/local/timbin:/local/dtp:/home/tim/bin
    PERL5LIB=:/local/perl5/site_perl/5.8.2:/usr/lib/perl5/site_perl/5.8.2:/local/perl5/site_perl/5.8.0:/usr/lib/perl5/site_perl/5.8.0:/local/perl5/site_perl/5.6.0:/local/perl5/site_perl/5.005:/local/perl5/site_perl/i386-linux:/usr/lib/perl5/site_perl/5.8.0/i586-linux-thread-multi
    PERL_BADLANG (unset)
    SHELL=/bin/bash

-------------- next part --------------
contix at jumpy:/tmp> date
Sat Jan 15 10:26:02 PST 2005

contix at jumpy:/tmp> nl -ba good
     1  #! /usr/bin/perl -s -wlnaF:
     2  print "Switch variable is: $switch";
     3  print "F1: $F[0], F2: $F[1]";

contix at jumpy:/tmp> date | ./good -switch=3
Switch variable is: 3
F1: Sat Jan 15 10, F2: 26

contix at jumpy:/tmp> nl -ba bad
     1  #! /usr/bin/perl -wlnaF: -s
     2  print "Switch variable is: $switch";
     3  print "F1: $F[0], F2: $F[1]";

contix at jumpy:/tmp> date | ./bad -switch=3
Name "main::switch" used only once: possible typo at ./bad line 2.
Can't open -switch=3: No such file or directory.

[The switch argument was incorrectly interpreted as a filename!]

contix at jumpy:/tmp> diff bad good
1c1
< #! /usr/bin/perl -wlnaF: -s
---
> #! /usr/bin/perl -s -wlnaF:
contix at jumpy:/tmp> 


More information about the spug-list mailing list