bobg+@andrew.cmu.edu (Robert Steven Glickstein) (02/12/91)
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: bobg@andrew.cmu.edu Information Technology Center | Bitnet: bobg%andrew@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
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/12/91)
In article <cbhl9z200VsnE1=K1b@andrew.cmu.edu> bobg+@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
fuchs@tmipi4.telematik.informatik.uni-karlsruhe.de (Harald Fuchs) (02/12/91)
lwall@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 <fuchs@tmipi4.telematik.informatik.uni-karlsruhe.de> <fuchs@telematik.informatik.uni-karlsruhe.dbp.de> *gulp*
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/12/91)
In article <fuchs.666322665@tmipi4> fuchs@tmipi4.telematik.informatik.uni-karlsruhe.de (Harald Fuchs) writes: : lwall@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
tneff@bfmny0.BFM.COM (Tom Neff) (02/12/91)
In article <11393@jpl-devvax.JPL.NASA.GOV> lwall@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//</);
tneff@bfmny0.BFM.COM (Tom Neff) (02/12/91)
In article <1991Feb12.165848.18718@convex.com> tchrist@convex.COM (Tom Christiansen) writes: >From the keyboard of tneff@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.
tchrist@convex.COM (Tom Christiansen) (02/13/91)
From the keyboard of tneff@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)
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/13/91)
In article <22434654@bfmny0.BFM.COM> tneff@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
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/13/91)
In article <1991Feb12.165848.18718@convex.com> tchrist@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