Novice surprise

159 views
Skip to first unread message

Robert Steven Glickstein

unread,
Feb 11, 1991, 4:54:07 PM2/11/91
to

Today I ran my very first Perl program; it was generated by a2p. The
awk program was:

BEGIN {x = 0}
$0 == "" {x = 1}
x == 1

The perl program produced was:

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;
# process any FOO=bar switches

$x = 0;

while (<>) {
chop; # strip record separator
if ($_ eq '') {
$x = 1;
}
print $_ if $x == 1;
}

The idea: skip the first lines of the input until a blank line is
found, then start echoing the lines. The awk program worked fine, the
perl program did not. I kept getting "cannot open file" errors.

It was two hours of staring at this stupid thing before I realized
that the problem was this: The filenames that I was passing as
arguments happened to begin with a "+". Since I didn't have
write-access, I got a "cannot open file" error. I couldn't figure out
a way to circumvent this in Perl, so instead of the command-line

perlscript +a +b +c

I used

perlscript ./+a ./+b ./+c

The big question: What is the *right* way around this problem?

______________ _____________________________
Bob Glickstein | Internet: bo...@andrew.cmu.edu
Information Technology Center | Bitnet: bobg%and...@cmuccvma.bitnet
Carnegie Mellon University | UUCP: ...!harvard!andrew.cmu.edu!bobg
Pittsburgh, PA 15213-3890 |
(412) 268-6743 | Sinners can repent, but stupid is forever

Larry Wall

unread,
Feb 11, 1991, 7:13:22 PM2/11/91
to
In article <cbhl9z200VsnE1=K...@andrew.cmu.edu> bo...@andrew.cmu.edu (Robert Steven Glickstein) writes:
: It was two hours of staring at this stupid thing before I realized

: that the problem was this: The filenames that I was passing as
: arguments happened to begin with a "+". Since I didn't have
: write-access, I got a "cannot open file" error. I couldn't figure out
: a way to circumvent this in Perl, so instead of the command-line
:
: perlscript +a +b +c
:
: I used
:
: perlscript ./+a ./+b ./+c
:
: The big question: What is the *right* way around this problem?

Er, don't use a toy language for a real problem... :-)

I think that most people avoid the problem by not using filenames beginning
with + or >. If you really want to write a bulletproof script, you might
put the following before the initial loop:

for (@ARGV) { s#^([^/])#./$1#; s#$#\0#; }
while (<>) {...

In general, filenames starting with + aren't quite as dangerous as those
starting with -, but there are some programs that use + to introduce
switches, so it's probably a bad idea. You can't, for example, say

sort +a +b +c

Just don't create a file called -rf. :-)

Larry

Harald Fuchs

unread,
Feb 11, 1991, 8:37:45 PM2/11/91
to
lw...@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:

>I think that most people avoid the problem by not using filenames beginning
>with + or >. If you really want to write a bulletproof script, you might
>put the following before the initial loop:

>for (@ARGV) { s#^([^/])#./$1#; s#$#\0#; }
>while (<>) {...

Shouldn't that be
for (@ARGV) { s#^[^./]#./$&#; s#$#\0#; }
Note the period: ^
--

Harald Fuchs <fu...@tmipi4.telematik.informatik.uni-karlsruhe.de>
<fu...@telematik.informatik.uni-karlsruhe.dbp.de> *gulp*

Larry Wall

unread,
Feb 11, 1991, 9:48:25 PM2/11/91
to
In article <fuchs.666322665@tmipi4> fu...@tmipi4.telematik.informatik.uni-karlsruhe.de (Harald Fuchs) writes:

: lw...@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
:
: >I think that most people avoid the problem by not using filenames beginning
: >with + or >. If you really want to write a bulletproof script, you might
: >put the following before the initial loop:
:
: >for (@ARGV) { s#^([^/])#./$1#; s#$#\0#; }
: >while (<>) {...
:
: Shouldn't that be
: for (@ARGV) { s#^[^./]#./$&#; s#$#\0#; }
: Note the period: ^

You can if it makes you feel better, but it doesn't hurt (much) to add an
extra ./ on the front of any relative pathname (even those beginning with .
or ..). The current directory will even be in the cache already, so there's
no extra disk access.

Larry

Tom Neff

unread,
Feb 12, 1991, 12:24:41 AM2/12/91
to
In article <11...@jpl-devvax.JPL.NASA.GOV> lw...@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>I think that most people avoid the problem by not using filenames beginning
>with + or >.

It's not always up to us, is it! Sometimes we need our Perl tools
just to DEAL with the weird stuff other peoples' programs create.

> If you really want to write a bulletproof script, you might
>put the following before the initial loop:
>
>for (@ARGV) { s#^([^/])#./$1#; s#$#\0#; }
>while (<>) {...

Nah, too complicated. Just

grep(ARGV,s//</);

Tom Christiansen

unread,
Feb 12, 1991, 11:58:48 AM2/12/91
to
From the keyboard of tn...@bfmny0.BFM.COM (Tom Neff):
:>[Larry said]
:> If you really want to write a bulletproof script, you might

:>put the following before the initial loop:
:>
:>for (@ARGV) { s#^([^/])#./$1#; s#$#\0#; }
:>while (<>) {...
:
:Nah, too complicated. Just
:
: grep(ARGV,s//</);

Hello? Don't you mean

grep(s//</, @ARGV);

It's kind of a pity perl doesn't flag this as an error.

And I would use s/^/</ myself -- I always think // will
be a remembered /pattern_match/, although in s/// it doesn't
seem to me. Maybe it only counts for m// things. Larry?

Also, Larry's works on things that Tom Neff's doesn't: you
can't open a file named "-" nor any with trailing white space
unless you use Larry's quotation mechanism, or it's functional
equivalent, like

grep(s#^([^/])(.*)#./$1$2\0#, @ARGV);

--tom
--
"All things are possible, but not all expedient." (in life, UNIX, and perl)

Larry Wall

unread,
Feb 12, 1991, 1:13:50 PM2/12/91
to
In article <2243...@bfmny0.BFM.COM> tn...@bfmny0.BFM.COM (Tom Neff) writes:
: Nah, too complicated. Just
:
: grep(ARGV,s//</);

Not complicated enough. (Not to mention backwards.) What if the filename
begins with &? What if // invokes a previous pattern? Try

grep(s/.*/< $&\0/, @ARGV);

And that still doesn't handle leading whitespace.

By the way, /foo/ && s//bar/ is busted in 44, seemingly. I'm looking at it.
/f../ && s//bar/ works right though. Looks like the constant string optimizer
got me.

Larry

Larry Wall

unread,
Feb 12, 1991, 1:18:42 PM2/12/91
to
In article <1991Feb12.1...@convex.com> tch...@convex.COM (Tom Christiansen) writes:
: Also, Larry's works on things that Tom Neff's doesn't: you

: can't open a file named "-" nor any with trailing white space
: unless you use Larry's quotation mechanism, or it's functional
: equivalent, like
:
: grep(s#^([^/])(.*)#./$1$2\0#, @ARGV);

Unfortunately, that's not a functional equivalent, since it won't put the
trailing null on an absolute pathname.

Larry

Tom Neff

unread,
Feb 12, 1991, 3:55:07 AM2/12/91
to
In article <1991Feb12.1...@convex.com> tch...@convex.COM (Tom Christiansen) writes:
>From the keyboard of tn...@bfmny0.BFM.COM (Tom Neff):
>: grep(ARGV,s//</);
>
>Hello? Don't you mean
>
> grep(s//</, @ARGV);
>
>It's kind of a pity perl doesn't flag this as an error.

Groooooaaannn! :-( --> :-)

I'll tell you what's really sick -- mine worked too! Go figure.

Reply all
Reply to author
Forward
0 new messages