Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Novice surprise

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

0 new messages