home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i084: Perl, a language with features of C/sed/awk/shell/etc, Part01/24
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
- Posting-number: Volume 20, Issue 84
- Archive-name: perl3.0/part01
-
- [ This is a first: perl3.0 is being distributed by Larry Wall under the
- terms of the GNU Copyright. Anyhow, if you haven't played with perl
- yet you're missing out on something great. /r$ ]
-
- Perl is a language that combines some of the features of C, sed, awk and shell.
- See the manual page for more hype.
-
- Perl will probably not run on machines with a small address space.
-
- Please read all the directions below before you proceed any further, and
- then follow them carefully.
-
-
- #! /bin/sh
-
- # Make a new directory for the perl sources, cd to it, and run kits 1
- # thru 24 through sh. When all 24 kits have been run, read README.
-
- echo "This is perl 3.0 kit 1 (of 24). If kit 1 is complete, the line"
- echo '"'"End of kit 1 (of 24)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir eg t 2>/dev/null
- echo Extracting README
- sed >README <<'!STUFFY!FUNK!' -e 's/X//'
- X
- X Perl Kit, Version 3.0
- X
- X Copyright (c) 1989, Larry Wall
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 1, or (at your option)
- X any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- X--------------------------------------------------------------------------
- X
- XPerl is a language that combines some of the features of C, sed, awk and shell.
- XSee the manual page for more hype.
- X
- XPerl will probably not run on machines with a small address space.
- X
- XPlease read all the directions below before you proceed any further, and
- Xthen follow them carefully.
- X
- XAfter you have unpacked your kit, you should have all the files listed
- Xin MANIFEST.
- X
- XInstallation
- X
- X1) Run Configure. This will figure out various things about your system.
- X Some things Configure will figure out for itself, other things it will
- X ask you about. It will then proceed to make config.h, config.sh, and
- X Makefile.
- X
- X You might possibly have to trim # comments from the front of Configure
- X if your sh doesn't handle them, but all other # comments will be taken
- X care of.
- X
- X (If you don't have sh, you'll have to copy the sample file config.H to
- X config.h and edit the config.h to reflect your system's peculiarities.)
- X
- X2) Glance through config.h to make sure system dependencies are correct.
- X Most of them should have been taken care of by running the Configure script.
- X
- X If you have any additional changes to make to the C definitions, they
- X can be done in the Makefile, or in config.h. Bear in mind that they will
- X get undone next time you run Configure.
- X
- X3) make depend
- X
- X This will look for all the includes and modify Makefile accordingly.
- X Configure will offer to do this for you.
- X
- X4) make
- X
- X This will attempt to make perl in the current directory.
- X
- X5) make test
- X
- X This will run the regression tests on the perl you just made.
- X If it doesn't say "All tests successful" then something went wrong.
- X See the README in the t subdirectory. Note that you can't run it
- X in background if this disables opening of /dev/tty. If in doubt, just
- X cd to the t directory and run TEST by hand.
- X
- X6) make install
- X
- X This will put perl into a public directory (such as /usr/local/bin).
- X It will also try to put the man pages in a reasonable place. It will not
- X nroff the man page, however. You may need to be root to do this. If
- X you are not root, you must own the directories in question and you should
- X ignore any messages about chown not working.
- X
- X7) Read the manual entry before running perl.
- X
- X8) IMPORTANT! Help save the world! Communicate any problems and suggested
- X patches to me, lwall@jpl-devvax.jpl.nasa.gov (Larry Wall), so we can
- X keep the world in sync. If you have a problem, there's someone else
- X out there who either has had or will have the same problem.
- X
- X If possible, send in patches such that the patch program will apply them.
- X Context diffs are the best, then normal diffs. Don't send ed scripts--
- X I've probably changed my copy since the version you have.
- X
- X Watch for perl patches in comp.sources.bugs. Patches will generally be
- X in a form usable by the patch program. If you are just now bringing up
- X perl and aren't sure how many patches there are, write to me and I'll
- X send any you don't have. Your current patch level is shown in patchlevel.h.
- X
- X
- XJust a personal note: I want you to know that I create nice things like this
- Xbecause it pleases the Author of my story. If this bothers you, then your
- Xnotion of Authorship needs some revision. But you can use perl anyway. :-)
- X
- X The author.
- !STUFFY!FUNK!
- echo Extracting eg/README
- sed >eg/README <<'!STUFFY!FUNK!' -e 's/X//'
- XThis stuff is supplied on an as-is basis--little attempt has been made to make
- Xany of it portable. It's mostly here to give you an idea of what perl code
- Xlooks like, and what tricks and idioms are used.
- X
- XSystem administrators responsible for many computers will enjoy the items
- Xdown in the g directory very much. The scan directory contains the beginnings
- Xof a system to check on and report various kinds of anomalies.
- X
- XIf you machine doesn't support #!, the first thing you'll want to do is
- Xreplace the #! with a couple of lines that look like this:
- X
- X eval "exec /usr/bin/perl -S $0 $*"
- X if $running_under_some_shell;
- X
- Xbeing sure to include any flags that were on the #! line. A supplied script
- Xcalled "nih" will translate perl scripts in place for you:
- X
- X nih g/g??
- !STUFFY!FUNK!
- echo Extracting t/README
- sed >t/README <<'!STUFFY!FUNK!' -e 's/X//'
- XThis is the perl test library. To run all the tests, just type 'TEST'.
- X
- XTo add new tests, just look at the current tests and do likewise.
- X
- XIf a test fails, run it by itself to see if it prints any informative
- Xdiagnostics. If not, modify the test to print informative diagnostics.
- XIf you put out extra lines with a '#' character on the front, you don't
- Xhave to worry about removing the extra print statements later since TEST
- Xignores lines beginning with '#'.
- X
- XIf you come up with new tests, send them to lwall@jpl-devvax.jpl.nasa.gov.
- !STUFFY!FUNK!
- echo Extracting perl.man.1
- sed >perl.man.1 <<'!STUFFY!FUNK!' -e 's/X//'
- X.rn '' }`
- X''' $Header: perl.man.1,v 3.0 89/10/18 15:21:29 lwall Locked $
- X'''
- X''' $Log: perl.man.1,v $
- X''' Revision 3.0 89/10/18 15:21:29 lwall
- X''' 3.0 baseline
- X'''
- X'''
- X.de Sh
- X.br
- X.ne 5
- X.PP
- X\fB\\$1\fR
- X.PP
- X..
- X.de Sp
- X.if t .sp .5v
- X.if n .sp
- X..
- X.de Ip
- X.br
- X.ie \\n.$>=3 .ne \\$3
- X.el .ne 3
- X.IP "\\$1" \\$2
- X..
- X'''
- X''' Set up \*(-- to give an unbreakable dash;
- X''' string Tr holds user defined translation string.
- X''' Bell System Logo is used as a dummy character.
- X'''
- X.tr \(*W-|\(bv\*(Tr
- X.ie n \{\
- X.ds -- \(*W-
- X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
- X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
- X.ds L" ""
- X.ds R" ""
- X.ds L' '
- X.ds R' '
- X'br\}
- X.el\{\
- X.ds -- \(em\|
- X.tr \*(Tr
- X.ds L" ``
- X.ds R" ''
- X.ds L' `
- X.ds R' '
- X'br\}
- X.TH PERL 1 "\*(RP"
- X.UC
- X.SH NAME
- Xperl \- Practical Extraction and Report Language
- X.SH SYNOPSIS
- X.B perl
- X[options] filename args
- X.SH DESCRIPTION
- X.I Perl
- Xis an interpreted language optimized for scanning arbitrary text files,
- Xextracting information from those text files, and printing reports based
- Xon that information.
- XIt's also a good language for many system management tasks.
- XThe language is intended to be practical (easy to use, efficient, complete)
- Xrather than beautiful (tiny, elegant, minimal).
- XIt combines (in the author's opinion, anyway) some of the best features of C,
- X\fIsed\fR, \fIawk\fR, and \fIsh\fR,
- Xso people familiar with those languages should have little difficulty with it.
- X(Language historians will also note some vestiges of \fIcsh\fR, Pascal, and
- Xeven BASIC-PLUS.)
- XExpression syntax corresponds quite closely to C expression syntax.
- XUnlike most Unix utilities,
- X.I perl
- Xdoes not arbitrarily limit the size of your data\*(--if you've got
- Xthe memory,
- X.I perl
- Xcan slurp in your whole file as a single string.
- XRecursion is of unlimited depth.
- XAnd the hash tables used by associative arrays grow as necessary to prevent
- Xdegraded performance.
- X.I Perl
- Xuses sophisticated pattern matching techniques to scan large amounts of
- Xdata very quickly.
- XAlthough optimized for scanning text,
- X.I perl
- Xcan also deal with binary data, and can make dbm files look like associative
- Xarrays (where dbm is available).
- XSetuid
- X.I perl
- Xscripts are safer than C programs
- Xthrough a dataflow tracing mechanism which prevents many stupid security holes.
- XIf you have a problem that would ordinarily use \fIsed\fR
- Xor \fIawk\fR or \fIsh\fR, but it
- Xexceeds their capabilities or must run a little faster,
- Xand you don't want to write the silly thing in C, then
- X.I perl
- Xmay be for you.
- XThere are also translators to turn your
- X.I sed
- Xand
- X.I awk
- Xscripts into
- X.I perl
- Xscripts.
- XOK, enough hype.
- X.PP
- XUpon startup,
- X.I perl
- Xlooks for your script in one of the following places:
- X.Ip 1. 4 2
- XSpecified line by line via
- X.B \-e
- Xswitches on the command line.
- X.Ip 2. 4 2
- XContained in the file specified by the first filename on the command line.
- X(Note that systems supporting the #! notation invoke interpreters this way.)
- X.Ip 3. 4 2
- XPassed in implicitly via standard input.
- XThis only works if there are no filename arguments\*(--to pass
- Xarguments to a
- X.I stdin
- Xscript you must explicitly specify a \- for the script name.
- X.PP
- XAfter locating your script,
- X.I perl
- Xcompiles it to an internal form.
- XIf the script is syntactically correct, it is executed.
- X.Sh "Options"
- XNote: on first reading this section may not make much sense to you. It's here
- Xat the front for easy reference.
- X.PP
- XA single-character option may be combined with the following option, if any.
- XThis is particularly useful when invoking a script using the #! construct which
- Xonly allows one argument. Example:
- X.nf
- X
- X.ne 2
- X #!/usr/bin/perl \-spi.bak # same as \-s \-p \-i.bak
- X .\|.\|.
- X
- X.fi
- XOptions include:
- X.TP 5
- X.B \-a
- Xturns on autosplit mode when used with a
- X.B \-n
- Xor
- X.BR \-p .
- XAn implicit split command to the @F array
- Xis done as the first thing inside the implicit while loop produced by
- Xthe
- X.B \-n
- Xor
- X.BR \-p .
- X.nf
- X
- X perl \-ane \'print pop(@F), "\en";\'
- X
- Xis equivalent to
- X
- X while (<>) {
- X @F = split(\' \');
- X print pop(@F), "\en";
- X }
- X
- X.fi
- X.TP 5
- X.BI \-d
- Xruns the script under the perl debugger.
- XSee the section on Debugging.
- X.TP 5
- X.BI \-D number
- Xsets debugging flags.
- XTo watch how it executes your script, use
- X.BR \-D14 .
- X(This only works if debugging is compiled into your
- X.IR perl .)
- XAnother nice value is \-D1024, which lists your compiled syntax tree.
- XAnd \-D512 displays compiled regular expressions.
- X.TP 5
- X.BI \-e " commandline"
- Xmay be used to enter one line of script.
- XMultiple
- X.B \-e
- Xcommands may be given to build up a multi-line script.
- XIf
- X.B \-e
- Xis given,
- X.I perl
- Xwill not look for a script filename in the argument list.
- X.TP 5
- X.BI \-i extension
- Xspecifies that files processed by the <> construct are to be edited
- Xin-place.
- XIt does this by renaming the input file, opening the output file by the
- Xsame name, and selecting that output file as the default for print statements.
- XThe extension, if supplied, is added to the name of the
- Xold file to make a backup copy.
- XIf no extension is supplied, no backup is made.
- XSaying \*(L"perl \-p \-i.bak \-e "s/foo/bar/;" .\|.\|. \*(R" is the same as using
- Xthe script:
- X.nf
- X
- X.ne 2
- X #!/usr/bin/perl \-pi.bak
- X s/foo/bar/;
- X
- Xwhich is equivalent to
- X
- X.ne 14
- X #!/usr/bin/perl
- X while (<>) {
- X if ($ARGV ne $oldargv) {
- X rename($ARGV, $ARGV . \'.bak\');
- X open(ARGVOUT, ">$ARGV");
- X select(ARGVOUT);
- X $oldargv = $ARGV;
- X }
- X s/foo/bar/;
- X }
- X continue {
- X print; # this prints to original filename
- X }
- X select(STDOUT);
- X
- X.fi
- Xexcept that the
- X.B \-i
- Xform doesn't need to compare $ARGV to $oldargv to know when
- Xthe filename has changed.
- XIt does, however, use ARGVOUT for the selected filehandle.
- XNote that
- X.I STDOUT
- Xis restored as the default output filehandle after the loop.
- X.Sp
- XYou can use eof to locate the end of each input file, in case you want
- Xto append to each file, or reset line numbering (see example under eof).
- X.TP 5
- X.BI \-I directory
- Xmay be used in conjunction with
- X.B \-P
- Xto tell the C preprocessor where to look for include files.
- XBy default /usr/include and /usr/lib/perl are searched.
- X.TP 5
- X.B \-n
- Xcauses
- X.I perl
- Xto assume the following loop around your script, which makes it iterate
- Xover filename arguments somewhat like \*(L"sed \-n\*(R" or \fIawk\fR:
- X.nf
- X
- X.ne 3
- X while (<>) {
- X .\|.\|. # your script goes here
- X }
- X
- X.fi
- XNote that the lines are not printed by default.
- XSee
- X.B \-p
- Xto have lines printed.
- XHere is an efficient way to delete all files older than a week:
- X.nf
- X
- X find . \-mtime +7 \-print | perl \-ne \'chop;unlink;\'
- X
- X.fi
- XThis is faster than using the \-exec switch of find because you don't have to
- Xstart a process on every filename found.
- X.TP 5
- X.B \-p
- Xcauses
- X.I perl
- Xto assume the following loop around your script, which makes it iterate
- Xover filename arguments somewhat like \fIsed\fR:
- X.nf
- X
- X.ne 5
- X while (<>) {
- X .\|.\|. # your script goes here
- X } continue {
- X print;
- X }
- X
- X.fi
- XNote that the lines are printed automatically.
- XTo suppress printing use the
- X.B \-n
- Xswitch.
- XA
- X.B \-p
- Xoverrides a
- X.B \-n
- Xswitch.
- X.TP 5
- X.B \-P
- Xcauses your script to be run through the C preprocessor before
- Xcompilation by
- X.IR perl .
- X(Since both comments and cpp directives begin with the # character,
- Xyou should avoid starting comments with any words recognized
- Xby the C preprocessor such as \*(L"if\*(R", \*(L"else\*(R" or \*(L"define\*(R".)
- X.TP 5
- X.B \-s
- Xenables some rudimentary switch parsing for switches on the command line
- Xafter the script name but before any filename arguments (or before a \-\|\-).
- XAny switch found there is removed from @ARGV and sets the corresponding variable in the
- X.I perl
- Xscript.
- XThe following script prints \*(L"true\*(R" if and only if the script is
- Xinvoked with a \-xyz switch.
- X.nf
- X
- X.ne 2
- X #!/usr/bin/perl \-s
- X if ($xyz) { print "true\en"; }
- X
- X.fi
- X.TP 5
- X.B \-S
- Xmakes
- X.I perl
- Xuse the PATH environment variable to search for the script
- X(unless the name of the script starts with a slash).
- XTypically this is used to emulate #! startup on machines that don't
- Xsupport #!, in the following manner:
- X.nf
- X
- X #!/usr/bin/perl
- X eval "exec /usr/bin/perl \-S $0 $*"
- X if $running_under_some_shell;
- X
- X.fi
- XThe system ignores the first line and feeds the script to /bin/sh,
- Xwhich proceeds to try to execute the
- X.I perl
- Xscript as a shell script.
- XThe shell executes the second line as a normal shell command, and thus
- Xstarts up the
- X.I perl
- Xinterpreter.
- XOn some systems $0 doesn't always contain the full pathname,
- Xso the
- X.B \-S
- Xtells
- X.I perl
- Xto search for the script if necessary.
- XAfter
- X.I perl
- Xlocates the script, it parses the lines and ignores them because
- Xthe variable $running_under_some_shell is never true.
- X.TP 5
- X.B \-u
- Xcauses
- X.I perl
- Xto dump core after compiling your script.
- XYou can then take this core dump and turn it into an executable file
- Xby using the undump program (not supplied).
- XThis speeds startup at the expense of some disk space (which you can
- Xminimize by stripping the executable).
- X(Still, a "hello world" executable comes out to about 200K on my machine.)
- XIf you are going to run your executable as a set-id program then you
- Xshould probably compile it using taintperl rather than normal perl.
- XIf you want to execute a portion of your script before dumping, use the
- Xdump operator instead.
- X.TP 5
- X.B \-U
- Xallows
- X.I perl
- Xto do unsafe operations.
- XCurrently the only \*(L"unsafe\*(R" operation is the unlinking of directories while
- Xrunning as superuser.
- X.TP 5
- X.B \-v
- Xprints the version and patchlevel of your
- X.I perl
- Xexecutable.
- X.TP 5
- X.B \-w
- Xprints warnings about identifiers that are mentioned only once, and scalar
- Xvariables that are used before being set.
- XAlso warns about redefined subroutines, and references to undefined
- Xfilehandles or filehandles opened readonly that you are attempting to
- Xwrite on.
- XAlso warns you if you use == on values that don't look like numbers, and if
- Xyour subroutines recurse more than 100 deep.
- X.Sh "Data Types and Objects"
- X.PP
- X.I Perl
- Xhas three data types: scalars, arrays of scalars, and
- Xassociative arrays of scalars.
- XNormal arrays are indexed by number, and associative arrays by string.
- X.PP
- XThe interpretation of operations and values in perl sometimes
- Xdepends on the requirements
- Xof the context around the operation or value.
- XThere are three major contexts: string, numeric and array.
- XCertain operations return array values
- Xin contexts wanting an array, and scalar values otherwise.
- X(If this is true of an operation it will be mentioned in the documentation
- Xfor that operation.)
- XOperations which return scalars don't care whether the context is looking
- Xfor a string or a number, but
- Xscalar variables and values are interpreted as strings or numbers
- Xas appropriate to the context.
- XA scalar is interpreted as TRUE in the boolean sense if it is not the null
- Xstring or 0.
- XBooleans returned by operators are 1 for true and \'0\' or \'\' (the null
- Xstring) for false.
- X.PP
- XThere are actually two varieties of null string: defined and undefined.
- XUndefined null strings are returned when there is no real value for something,
- Xsuch as when there was an error, or at end of file, or when you refer
- Xto an uninitialized variable or element of an array.
- XAn undefined null string may become defined the first time you access it, but
- Xprior to that you can use the defined() operator to determine whether the
- Xvalue is defined or not.
- X.PP
- XReferences to scalar variables always begin with \*(L'$\*(R', even when referring
- Xto a scalar that is part of an array.
- XThus:
- X.nf
- X
- X.ne 3
- X $days \h'|2i'# a simple scalar variable
- X $days[28] \h'|2i'# 29th element of array @days
- X $days{\'Feb\'}\h'|2i'# one value from an associative array
- X $#days \h'|2i'# last index of array @days
- X
- Xbut entire arrays or array slices are denoted by \*(L'@\*(R':
- X
- X @days \h'|2i'# ($days[0], $days[1],\|.\|.\|. $days[n])
- X @days[3,4,5]\h'|2i'# same as @days[3.\|.5]
- X @days{'a','c'}\h'|2i'# same as ($days{'a'},$days{'c'})
- X
- Xand entire associative arrays are denoted by \*(L'%\*(R':
- X
- X %days \h'|2i'# (key1, val1, key2, val2 .\|.\|.)
- X.fi
- X.PP
- XAny of these eight constructs may serve as an lvalue,
- Xthat is, may be assigned to.
- X(It also turns out that an assignment is itself an lvalue in
- Xcertain contexts\*(--see examples under s, tr and chop.)
- XAssignment to a scalar evaluates the righthand side in a scalar context,
- Xwhile assignment to an array or array slice evaluates the righthand side
- Xin an array context.
- X.PP
- XYou may find the length of array @days by evaluating
- X\*(L"$#days\*(R", as in
- X.IR csh .
- X(Actually, it's not the length of the array, it's the subscript of the last element, since there is (ordinarily) a 0th element.)
- XAssigning to $#days changes the length of the array.
- XShortening an array by this method does not actually destroy any values.
- XLengthening an array that was previously shortened recovers the values that
- Xwere in those elements.
- XYou can also gain some measure of efficiency by preextending an array that
- Xis going to get big.
- X(You can also extend an array by assigning to an element that is off the
- Xend of the array.
- XThis differs from assigning to $#whatever in that intervening values
- Xare set to null rather than recovered.)
- XYou can truncate an array down to nothing by assigning the null list () to
- Xit.
- XThe following are exactly equivalent
- X.nf
- X
- X @whatever = ();
- X $#whatever = $[ \- 1;
- X
- X.fi
- X.PP
- XMulti-dimensional arrays are not directly supported, but see the discussion
- Xof the $; variable later for a means of emulating multiple subscripts with
- Xan associative array.
- X.PP
- XEvery data type has its own namespace.
- XYou can, without fear of conflict, use the same name for a scalar variable,
- Xan array, an associative array, a filehandle, a subroutine name, and/or
- Xa label.
- XSince variable and array references always start with \*(L'$\*(R', \*(L'@\*(R',
- Xor \*(L'%\*(R', the \*(L"reserved\*(R" words aren't in fact reserved
- Xwith respect to variable names.
- X(They ARE reserved with respect to labels and filehandles, however, which
- Xdon't have an initial special character.
- XHint: you could say open(LOG,\'logfile\') rather than open(log,\'logfile\').
- XUsing uppercase filehandles also improves readability and protects you
- Xfrom conflict with future reserved words.)
- XCase IS significant\*(--\*(L"FOO\*(R", \*(L"Foo\*(R" and \*(L"foo\*(R" are all
- Xdifferent names.
- XNames which start with a letter may also contain digits and underscores.
- XNames which do not start with a letter are limited to one character,
- Xe.g. \*(L"$%\*(R" or \*(L"$$\*(R".
- X(Most of the one character names have a predefined significance to
- X.IR perl .
- XMore later.)
- X.PP
- XNumeric literals are specified in any of the usual floating point or
- Xinteger formats:
- X.nf
- X
- X.ne 5
- X 12345
- X 12345.67
- X .23E-10
- X 0xffff # hex
- X 0377 # octal
- X
- X.fi
- XString literals are delimited by either single or double quotes.
- XThey work much like shell quotes:
- Xdouble-quoted string literals are subject to backslash and variable
- Xsubstitution; single-quoted strings are not (except for \e\' and \e\e).
- XThe usual backslash rules apply for making characters such as newline, tab, etc.
- XYou can also embed newlines directly in your strings, i.e. they can end on
- Xa different line than they begin.
- XThis is nice, but if you forget your trailing quote, the error will not be
- Xreported until
- X.I perl
- Xfinds another line containing the quote character, which
- Xmay be much further on in the script.
- XVariable substitution inside strings is limited to scalar variables, normal
- Xarray values, and array slices.
- X(In other words, identifiers beginning with $ or @, followed by an optional
- Xbracketed expression as a subscript.)
- XThe following code segment prints out \*(L"The price is $100.\*(R"
- X.nf
- X
- X.ne 2
- X $Price = \'$100\';\h'|3.5i'# not interpreted
- X print "The price is $Price.\e\|n";\h'|3.5i'# interpreted
- X
- X.fi
- XNote that you can put curly brackets around the identifier to delimit it
- Xfrom following alphanumerics.
- X.PP
- XArray values are interpolated into double-quoted strings by joining all the
- Xelements of the array with the delimiter specified in the $" variable,
- Xspace by default.
- X(Since in versions of perl prior to 3.0 the @ character was not a metacharacter
- Xin double-quoted strings, the interpolation of @array, $array[EXPR],
- X@array[LIST], $array{EXPR}, or @array{LIST} only happens if array is
- Xreferenced elsewhere in the program or is predefined.)
- XThe following are equivalent:
- X.nf
- X
- X.ne 4
- X $temp = join($",@ARGV);
- X system "echo $temp";
- X
- X system "echo @ARGV";
- X
- X.fi
- XWithin search patterns (which also undergo double-quoteish substitution)
- Xthere is a bad ambiguity: Is /$foo[bar]/ to be
- Xinterpreted as /${foo}[bar]/ (where [bar] is a character class for the
- Xregular expression) or as /${foo[bar]}/ (where [bar] is the subscript to
- Xarray @foo)?
- XIf @foo doesn't otherwise exist, then it's obviously a character class.
- XIf @foo exists, perl takes a good guess about [bar], and is almost always right.
- XIf it does guess wrong, or if you're just plain paranoid,
- Xyou can force the correct interpretation with curly brackets as above.
- X.PP
- XA line-oriented form of quoting is based on the shell here-is syntax.
- XFollowing a << you specify a string to terminate the quoted material, and all lines
- Xfollowing the current line down to the terminating string are the value
- Xof the item.
- XThe terminating string may be either an identifier (a word), or some
- Xquoted text.
- XIf quoted, the type of quotes you use determines the treatment of the text,
- Xjust as in regular quoting.
- XAn unquoted identifier works like double quotes.
- XThere must be no space between the << and the identifier.
- X(If you put a space it will be treated as a null identifier, which is
- Xvalid, and matches the first blank line\*(--see Merry Christmas example below.)
- XThe terminating string must appear by itself (unquoted and with no surrounding
- Xwhitespace) on the terminating line.
- X.nf
- X
- X print <<EOF; # same as above
- XThe price is $Price.
- XEOF
- X
- X print <<"EOF"; # same as above
- XThe price is $Price.
- XEOF
- X
- X print << x 10; # null identifier is delimiter
- XMerry Christmas!
- X
- X print <<`EOC`; # execute commands
- Xecho hi there
- Xecho lo there
- XEOC
- X
- X print <<foo, <<bar; # you can stack them
- XI said foo.
- Xfoo
- XI said bar.
- Xbar
- X
- X.fi
- XArray literals are denoted by separating individual values by commas, and
- Xenclosing the list in parentheses.
- XIn a context not requiring an array value, the value of the array literal
- Xis the value of the final element, as in the C comma operator.
- XFor example,
- X.nf
- X
- X.ne 4
- X @foo = (\'cc\', \'\-E\', $bar);
- X
- Xassigns the entire array value to array foo, but
- X
- X $foo = (\'cc\', \'\-E\', $bar);
- X
- X.fi
- Xassigns the value of variable bar to variable foo.
- XArray lists may be assigned to if and only if each element of the list
- Xis an lvalue:
- X.nf
- X
- X ($a, $b, $c) = (1, 2, 3);
- X
- X ($map{\'red\'}, $map{\'blue\'}, $map{\'green\'}) = (0x00f, 0x0f0, 0xf00);
- X
- XThe final element may be an array or an associative array:
- X
- X ($a, $b, @rest) = split;
- X local($a, $b, %rest) = @_;
- X
- X.fi
- XYou can actually put an array anywhere in the list, but the first array
- Xin the list will soak up all the values, and anything after it will get
- Xa null value.
- XThis may be useful in a local().
- X.PP
- XAn associative array literal contains pairs of values to be interpreted
- Xas a key and a value:
- X.nf
- X
- X.ne 2
- X # same as map assignment above
- X %map = ('red',0x00f,'blue',0x0f0,'green',0xf00);
- X
- X.fi
- XArray assignment in a scalar context returns the number of elements
- Xproduced by the expression on the right side of the assignment:
- X.nf
- X
- X $x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2
- X
- X.fi
- X.PP
- XThere are several other pseudo-literals that you should know about.
- XIf a string is enclosed by backticks (grave accents), it first undergoes
- Xvariable substitution just like a double quoted string.
- XIt is then interpreted as a command, and the output of that command
- Xis the value of the pseudo-literal, like in a shell.
- XThe command is executed each time the pseudo-literal is evaluated.
- XThe status value of the command is returned in $? (see Predefined Names
- Xfor the interpretation of $?).
- XUnlike in \f2csh\f1, no translation is done on the return
- Xdata\*(--newlines remain newlines.
- XUnlike in any of the shells, single quotes do not hide variable names
- Xin the command from interpretation.
- XTo pass a $ through to the shell you need to hide it with a backslash.
- X.PP
- XEvaluating a filehandle in angle brackets yields the next line
- Xfrom that file (newline included, so it's never false until EOF, at
- Xwhich time an undefined value is returned).
- XOrdinarily you must assign that value to a variable,
- Xbut there is one situation where in which an automatic assignment happens.
- XIf (and only if) the input symbol is the only thing inside the conditional of a
- X.I while
- Xloop, the value is
- Xautomatically assigned to the variable \*(L"$_\*(R".
- X(This may seem like an odd thing to you, but you'll use the construct
- Xin almost every
- X.I perl
- Xscript you write.)
- XAnyway, the following lines are equivalent to each other:
- X.nf
- X
- X.ne 5
- X while ($_ = <STDIN>) { print; }
- X while (<STDIN>) { print; }
- X for (\|;\|<STDIN>;\|) { print; }
- X print while $_ = <STDIN>;
- X print while <STDIN>;
- X
- X.fi
- XThe filehandles
- X.IR STDIN ,
- X.I STDOUT
- Xand
- X.I STDERR
- Xare predefined.
- X(The filehandles
- X.IR stdin ,
- X.I stdout
- Xand
- X.I stderr
- Xwill also work except in packages, where they would be interpreted as
- Xlocal identifiers rather than global.)
- XAdditional filehandles may be created with the
- X.I open
- Xfunction.
- X.PP
- XIf a <FILEHANDLE> is used in a context that is looking for an array, an array
- Xconsisting of all the input lines is returned, one line per array element.
- XIt's easy to make a LARGE data space this way, so use with care.
- X.PP
- XThe null filehandle <> is special and can be used to emulate the behavior of
- X\fIsed\fR and \fIawk\fR.
- XInput from <> comes either from standard input, or from each file listed on
- Xthe command line.
- XHere's how it works: the first time <> is evaluated, the ARGV array is checked,
- Xand if it is null, $ARGV[0] is set to \'-\', which when opened gives you standard
- Xinput.
- XThe ARGV array is then processed as a list of filenames.
- XThe loop
- X.nf
- X
- X.ne 3
- X while (<>) {
- X .\|.\|. # code for each line
- X }
- X
- X.ne 10
- Xis equivalent to
- X
- X unshift(@ARGV, \'\-\') \|if \|$#ARGV < $[;
- X while ($ARGV = shift) {
- X open(ARGV, $ARGV);
- X while (<ARGV>) {
- X .\|.\|. # code for each line
- X }
- X }
- X
- X.fi
- Xexcept that it isn't as cumbersome to say.
- XIt really does shift array ARGV and put the current filename into
- Xvariable ARGV.
- XIt also uses filehandle ARGV internally.
- XYou can modify @ARGV before the first <> as long as you leave the first
- Xfilename at the beginning of the array.
- XLine numbers ($.) continue as if the input was one big happy file.
- X(But see example under eof for how to reset line numbers on each file.)
- X.PP
- X.ne 5
- XIf you want to set @ARGV to your own list of files, go right ahead.
- XIf you want to pass switches into your script, you can
- Xput a loop on the front like this:
- X.nf
- X
- X.ne 10
- X while ($_ = $ARGV[0], /\|^\-/\|) {
- X shift;
- X last if /\|^\-\|\-$\|/\|;
- X /\|^\-D\|(.*\|)/ \|&& \|($debug = $1);
- X /\|^\-v\|/ \|&& \|$verbose++;
- X .\|.\|. # other switches
- X }
- X while (<>) {
- X .\|.\|. # code for each line
- X }
- X
- X.fi
- XThe <> symbol will return FALSE only once.
- XIf you call it again after this it will assume you are processing another
- X@ARGV list, and if you haven't set @ARGV, will input from
- X.IR STDIN .
- X.PP
- XIf the string inside the angle brackets is a reference to a scalar variable
- X(e.g. <$foo>),
- Xthen that variable contains the name of the filehandle to input from.
- X.PP
- XIf the string inside angle brackets is not a filehandle, it is interpreted
- Xas a filename pattern to be globbed, and either an array of filenames or the
- Xnext filename in the list is returned, depending on context.
- XOne level of $ interpretation is done first, but you can't say <$foo>
- Xbecause that's an indirect filehandle as explained in the previous
- Xparagraph.
- XYou could insert curly brackets to force interpretation as a
- Xfilename glob: <${foo}>.
- XExample:
- X.nf
- X
- X.ne 3
- X while (<*.c>) {
- X chmod 0644, $_;
- X }
- X
- Xis equivalent to
- X
- X.ne 5
- X open(foo, "echo *.c | tr \-s \' \et\er\ef\' \'\e\e012\e\e012\e\e012\e\e012\'|");
- X while (<foo>) {
- X chop;
- X chmod 0644, $_;
- X }
- X
- X.fi
- XIn fact, it's currently implemented that way.
- X(Which means it will not work on filenames with spaces in them unless
- Xyou have /bin/csh on your machine.)
- XOf course, the shortest way to do the above is:
- X.nf
- X
- X chmod 0644, <*.c>;
- X
- X.fi
- X.Sh "Syntax"
- X.PP
- XA
- X.I perl
- Xscript consists of a sequence of declarations and commands.
- XThe only things that need to be declared in
- X.I perl
- Xare report formats and subroutines.
- XSee the sections below for more information on those declarations.
- XAll uninitialized objects user-created objects are assumed to
- Xstart with a null or 0 value until they
- Xare defined by some explicit operation such as assignment.
- XThe sequence of commands is executed just once, unlike in
- X.I sed
- Xand
- X.I awk
- Xscripts, where the sequence of commands is executed for each input line.
- XWhile this means that you must explicitly loop over the lines of your input file
- X(or files), it also means you have much more control over which files and which
- Xlines you look at.
- X(Actually, I'm lying\*(--it is possible to do an implicit loop with either the
- X.B \-n
- Xor
- X.B \-p
- Xswitch.)
- X.PP
- XA declaration can be put anywhere a command can, but has no effect on the
- Xexecution of the primary sequence of commands--declarations all take effect
- Xat compile time.
- XTypically all the declarations are put at the beginning or the end of the script.
- X.PP
- X.I Perl
- Xis, for the most part, a free-form language.
- X(The only exception to this is format declarations, for fairly obvious reasons.)
- XComments are indicated by the # character, and extend to the end of the line.
- XIf you attempt to use /* */ C comments, it will be interpreted either as
- Xdivision or pattern matching, depending on the context.
- XSo don't do that.
- X.Sh "Compound statements"
- XIn
- X.IR perl ,
- Xa sequence of commands may be treated as one command by enclosing it
- Xin curly brackets.
- XWe will call this a BLOCK.
- X.PP
- XThe following compound commands may be used to control flow:
- X.nf
- X
- X.ne 4
- X if (EXPR) BLOCK
- X if (EXPR) BLOCK else BLOCK
- X if (EXPR) BLOCK elsif (EXPR) BLOCK .\|.\|. else BLOCK
- X LABEL while (EXPR) BLOCK
- X LABEL while (EXPR) BLOCK continue BLOCK
- X LABEL for (EXPR; EXPR; EXPR) BLOCK
- X LABEL foreach VAR (ARRAY) BLOCK
- X LABEL BLOCK continue BLOCK
- X
- X.fi
- XNote that, unlike C and Pascal, these are defined in terms of BLOCKs, not
- Xstatements.
- XThis means that the curly brackets are \fIrequired\fR\*(--no dangling statements allowed.
- XIf you want to write conditionals without curly brackets there are several
- Xother ways to do it.
- XThe following all do the same thing:
- X.nf
- X
- X.ne 5
- X if (!open(foo)) { die "Can't open $foo: $!"; }
- X die "Can't open $foo: $!" unless open(foo);
- X open(foo) || die "Can't open $foo: $!"; # foo or bust!
- X open(foo) ? die "Can't open $foo: $!" : \'hi mom\';
- X # a bit exotic, that last one
- X
- X.fi
- X.PP
- XThe
- X.I if
- Xstatement is straightforward.
- XSince BLOCKs are always bounded by curly brackets, there is never any
- Xambiguity about which
- X.I if
- Xan
- X.I else
- Xgoes with.
- XIf you use
- X.I unless
- Xin place of
- X.IR if ,
- Xthe sense of the test is reversed.
- X.PP
- XThe
- X.I while
- Xstatement executes the block as long as the expression is true
- X(does not evaluate to the null string or 0).
- XThe LABEL is optional, and if present, consists of an identifier followed by
- Xa colon.
- XThe LABEL identifies the loop for the loop control statements
- X.IR next ,
- X.IR last ,
- Xand
- X.I redo
- X(see below).
- XIf there is a
- X.I continue
- XBLOCK, it is always executed just before
- Xthe conditional is about to be evaluated again, similarly to the third part
- Xof a
- X.I for
- Xloop in C.
- XThus it can be used to increment a loop variable, even when the loop has
- Xbeen continued via the
- X.I next
- Xstatement (similar to the C \*(L"continue\*(R" statement).
- X.PP
- XIf the word
- X.I while
- Xis replaced by the word
- X.IR until ,
- Xthe sense of the test is reversed, but the conditional is still tested before
- Xthe first iteration.
- X.PP
- XIn either the
- X.I if
- Xor the
- X.I while
- Xstatement, you may replace \*(L"(EXPR)\*(R" with a BLOCK, and the conditional
- Xis true if the value of the last command in that block is true.
- X.PP
- XThe
- X.I for
- Xloop works exactly like the corresponding
- X.I while
- Xloop:
- X.nf
- X
- X.ne 12
- X for ($i = 1; $i < 10; $i++) {
- X .\|.\|.
- X }
- X
- Xis the same as
- X
- X $i = 1;
- X while ($i < 10) {
- X .\|.\|.
- X } continue {
- X $i++;
- X }
- X.fi
- X.PP
- XThe foreach loop iterates over a normal array value and sets the variable
- XVAR to be each element of the array in turn.
- XThe \*(L"foreach\*(R" keyword is actually identical to the \*(L"for\*(R" keyword,
- Xso you can use \*(L"foreach\*(R" for readability or \*(L"for\*(R" for brevity.
- XIf VAR is omitted, $_ is set to each value.
- XIf ARRAY is an actual array (as opposed to an expression returning an array
- Xvalue), you can modify each element of the array
- Xby modifying VAR inside the loop.
- XExamples:
- X.nf
- X
- X.ne 5
- X for (@ary) { s/foo/bar/; }
- X
- X foreach $elem (@elements) {
- X $elem *= 2;
- X }
- X
- X.ne 3
- X for ((10,9,8,7,6,5,4,3,2,1,\'BOOM\')) {
- X print $_, "\en"; sleep(1);
- X }
- X
- X for (1..15) { print "Merry Christmas\en"; }
- X
- X.ne 3
- X foreach $item (split(/:[\e\e\en:]*/, $ENV{\'TERMCAP\'}) {
- X print "Item: $item\en";
- X }
- X
- X.fi
- X.PP
- XThe BLOCK by itself (labeled or not) is equivalent to a loop that executes
- Xonce.
- XThus you can use any of the loop control statements in it to leave or
- Xrestart the block.
- XThe
- X.I continue
- Xblock is optional.
- XThis construct is particularly nice for doing case structures.
- X.nf
- X
- X.ne 6
- X foo: {
- X if (/^abc/) { $abc = 1; last foo; }
- X if (/^def/) { $def = 1; last foo; }
- X if (/^xyz/) { $xyz = 1; last foo; }
- X $nothing = 1;
- X }
- X
- X.fi
- XThere is no official switch statement in perl, because there
- Xare already several ways to write the equivalent.
- XIn addition to the above, you could write
- X.nf
- X
- X.ne 6
- X foo: {
- X $abc = 1, last foo if /^abc/;
- X $def = 1, last foo if /^def/;
- X $xyz = 1, last foo if /^xyz/;
- X $nothing = 1;
- X }
- X
- Xor
- X
- X.ne 6
- X foo: {
- X /^abc/ && do { $abc = 1; last foo; }
- X /^def/ && do { $def = 1; last foo; }
- X /^xyz/ && do { $xyz = 1; last foo; }
- X $nothing = 1;
- X }
- X
- Xor
- X
- X.ne 6
- X foo: {
- X /^abc/ && ($abc = 1, last foo);
- X /^def/ && ($def = 1, last foo);
- X /^xyz/ && ($xyz = 1, last foo);
- X $nothing = 1;
- X }
- X
- Xor even
- X
- X.ne 8
- X if (/^abc/)
- X { $abc = 1; last foo; }
- X elsif (/^def/)
- X { $def = 1; last foo; }
- X elsif (/^xyz/)
- X { $xyz = 1; last foo; }
- X else
- X {$nothing = 1;}
- X
- X.fi
- XAs it happens, these are all optimized internally to a switch structure,
- Xso perl jumps directly to the desired statement, and you needn't worry
- Xabout perl executing a lot of unnecessary statements when you have a string
- Xof 50 elsifs, as long as you are testing the same simple scalar variable
- Xusing ==, eq, or pattern matching as above.
- X(If you're curious as to whether the optimizer has done this for a particular
- Xcase statement, you can use the \-D1024 switch to list the syntax tree
- Xbefore execution.)
- X.Sh "Simple statements"
- XThe only kind of simple statement is an expression evaluated for its side
- Xeffects.
- XEvery expression (simple statement) must be terminated with a semicolon.
- XNote that this is like C, but unlike Pascal (and
- X.IR awk ).
- X.PP
- XAny simple statement may optionally be followed by a
- Xsingle modifier, just before the terminating semicolon.
- XThe possible modifiers are:
- X.nf
- X
- X.ne 4
- X if EXPR
- X unless EXPR
- X while EXPR
- X until EXPR
- X
- X.fi
- XThe
- X.I if
- Xand
- X.I unless
- Xmodifiers have the expected semantics.
- XThe
- X.I while
- Xand
- X.I until
- Xmodifiers also have the expected semantics (conditional evaluated first),
- Xexcept when applied to a do-BLOCK command,
- Xin which case the block executes once before the conditional is evaluated.
- XThis is so that you can write loops like:
- X.nf
- X
- X.ne 4
- X do {
- X $_ = <STDIN>;
- X .\|.\|.
- X } until $_ \|eq \|".\|\e\|n";
- X
- X.fi
- X(See the
- X.I do
- Xoperator below. Note also that the loop control commands described later will
- XNOT work in this construct, since modifiers don't take loop labels.
- XSorry.)
- X.Sh "Expressions"
- XSince
- X.I perl
- Xexpressions work almost exactly like C expressions, only the differences
- Xwill be mentioned here.
- X.PP
- XHere's what
- X.I perl
- Xhas that C doesn't:
- X.Ip ** 8 2
- XThe exponentiation operator.
- X.Ip **= 8
- XThe exponentiation assignment operator.
- X.Ip (\|) 8 3
- XThe null list, used to initialize an array to null.
- X.Ip . 8
- XConcatenation of two strings.
- X.Ip .= 8
- XThe concatenation assignment operator.
- X.Ip eq 8
- XString equality (== is numeric equality).
- XFor a mnemonic just think of \*(L"eq\*(R" as a string.
- X(If you are used to the
- X.I awk
- Xbehavior of using == for either string or numeric equality
- Xbased on the current form of the comparands, beware!
- XYou must be explicit here.)
- X.Ip ne 8
- XString inequality (!= is numeric inequality).
- X.Ip lt 8
- XString less than.
- X.Ip gt 8
- XString greater than.
- X.Ip le 8
- XString less than or equal.
- X.Ip ge 8
- XString greater than or equal.
- X.Ip =~ 8 2
- XCertain operations search or modify the string \*(L"$_\*(R" by default.
- XThis operator makes that kind of operation work on some other string.
- XThe right argument is a search pattern, substitution, or translation.
- XThe left argument is what is supposed to be searched, substituted, or
- Xtranslated instead of the default \*(L"$_\*(R".
- XThe return value indicates the success of the operation.
- X(If the right argument is an expression other than a search pattern,
- Xsubstitution, or translation, it is interpreted as a search pattern
- Xat run time.
- XThis is less efficient than an explicit search, since the pattern must
- Xbe compiled every time the expression is evaluated.)
- XThe precedence of this operator is lower than unary minus and autoincrement/decrement, but higher than everything else.
- X.Ip !~ 8
- XJust like =~ except the return value is negated.
- X.Ip x 8
- XThe repetition operator.
- XReturns a string consisting of the left operand repeated the
- Xnumber of times specified by the right operand.
- X.nf
- X
- X print \'\-\' x 80; # print row of dashes
- X print \'\-\' x80; # illegal, x80 is identifier
- X
- X print "\et" x ($tab/8), \' \' x ($tab%8); # tab over
- X
- X.fi
- X.Ip x= 8
- XThe repetition assignment operator.
- X.Ip .\|. 8
- XThe range operator, which is really two different operators depending
- Xon the context.
- XIn an array context, returns an array of values counting (by ones)
- Xfrom the left value to the right value.
- XThis is useful for writing \*(L"for (1..10)\*(R" loops and for doing
- Xslice operations on arrays.
- X.Sp
- XIn a scalar context, .\|. returns a boolean value.
- XThe operator is bistable, like a flip-flop..
- XEach .\|. operator maintains its own boolean state.
- XIt is false as long as its left operand is false.
- XOnce the left operand is true, the range operator stays true
- Xuntil the right operand is true,
- XAFTER which the range operator becomes false again.
- X(It doesn't become false till the next time the range operator is evaluated.
- XIt can become false on the same evaluation it became true, but it still returns
- Xtrue once.)
- XThe right operand is not evaluated while the operator is in the \*(L"false\*(R" state,
- Xand the left operand is not evaluated while the operator is in the \*(L"true\*(R" state.
- XThe scalar .\|. operator is primarily intended for doing line number ranges
- Xafter
- Xthe fashion of \fIsed\fR or \fIawk\fR.
- XThe precedence is a little lower than || and &&.
- XThe value returned is either the null string for false, or a sequence number
- X(beginning with 1) for true.
- XThe sequence number is reset for each range encountered.
- XThe final sequence number in a range has the string \'E0\' appended to it, which
- Xdoesn't affect its numeric value, but gives you something to search for if you
- Xwant to exclude the endpoint.
- XYou can exclude the beginning point by waiting for the sequence number to be
- Xgreater than 1.
- XIf either operand of scalar .\|. is static, that operand is implicitly compared
- Xto the $. variable, the current line number.
- XExamples:
- X.nf
- X
- X.ne 6
- XAs a scalar operator:
- X if (101 .\|. 200) { print; } # print 2nd hundred lines
- X
- X next line if (1 .\|. /^$/); # skip header lines
- X
- X s/^/> / if (/^$/ .\|. eof()); # quote body
- X
- X.ne 4
- XAs an array operator:
- X for (101 .\|. 200) { print; } # print $_ 100 times
- X
- X @foo = @foo[$[ .\|. $#foo]; # an expensive no-op
- X @foo = @foo[$#foo-4 .\|. $#foo]; # slice last 5 items
- X
- X.fi
- X.Ip \-x 8
- XA file test.
- XThis unary operator takes one argument, either a filename or a filehandle,
- Xand tests the associated file to see if something is true about it.
- XIf the argument is omitted, tests $_, except for \-t, which tests
- X.IR STDIN .
- XIt returns 1 for true and \'\' for false, or the undefined value if the
- Xfile doesn't exist.
- XPrecedence is higher than logical and relational operators, but lower than
- Xarithmetic operators.
- XThe operator may be any of:
- X.nf
- X \-r File is readable by effective uid.
- X \-w File is writable by effective uid.
- X \-x File is executable by effective uid.
- X \-o File is owned by effective uid.
- X \-R File is readable by real uid.
- X \-W File is writable by real uid.
- X \-X File is executable by real uid.
- X \-O File is owned by real uid.
- X \-e File exists.
- X \-z File has zero size.
- X \-s File has non-zero size.
- X \-f File is a plain file.
- X \-d File is a directory.
- X \-l File is a symbolic link.
- X \-p File is a named pipe (FIFO).
- X \-S File is a socket.
- X \-b File is a block special file.
- X \-c File is a character special file.
- X \-u File has setuid bit set.
- X \-g File has setgid bit set.
- X \-k File has sticky bit set.
- X \-t Filehandle is opened to a tty.
- X \-T File is a text file.
- X \-B File is a binary file (opposite of \-T).
- X
- X.fi
- XThe interpretation of the file permission operators \-r, \-R, \-w, \-W, \-x and \-X
- Xis based solely on the mode of the file and the uids and gids of the user.
- XThere may be other reasons you can't actually read, write or execute the file.
- XAlso note that, for the superuser, \-r, \-R, \-w and \-W always return 1, and
- X\-x and \-X return 1 if any execute bit is set in the mode.
- XScripts run by the superuser may thus need to do a stat() in order to determine
- Xthe actual mode of the file, or temporarily set the uid to something else.
- X.Sp
- XExample:
- X.nf
- X.ne 7
- X
- X while (<>) {
- X chop;
- X next unless \-f $_; # ignore specials
- X .\|.\|.
- X }
- X
- X.fi
- XNote that \-s/a/b/ does not do a negated substitution.
- XSaying \-exp($foo) still works as expected, however\*(--only single letters
- Xfollowing a minus are interpreted as file tests.
- X.Sp
- XThe \-T and \-B switches work as follows.
- XThe first block or so of the file is examined for odd characters such as
- Xstrange control codes or metacharacters.
- XIf too many odd characters (>10%) are found, it's a \-B file, otherwise it's a \-T file.
- XAlso, any file containing null in the first block is considered a binary file.
- XIf \-T or \-B is used on a filehandle, the current stdio buffer is examined
- Xrather than the first block.
- XBoth \-T and \-B return TRUE on a null file, or a file at EOF when testing
- Xa filehandle.
- X.PP
- XIf any of the file tests (or either stat operator) are given the special
- Xfilehandle consisting of a solitary underline, then the stat structure
- Xof the previous file test (or stat operator) is used, saving a system
- Xcall.
- X(This doesn't work with \-t, and you need to remember that lstat and -l
- Xwill leave values in the stat structure for the symbolic link, not the
- Xreal file.)
- XExample:
- X.nf
- X
- X print "Can do.\en" if -r $a || -w _ || -x _;
- X
- X.ne 9
- X stat($filename);
- X print "Readable\en" if -r _;
- X print "Writable\en" if -w _;
- X print "Executable\en" if -x _;
- X print "Setuid\en" if -u _;
- X print "Setgid\en" if -g _;
- X print "Sticky\en" if -k _;
- X print "Text\en" if -T _;
- X print "Binary\en" if -B _;
- X
- X.fi
- X.PP
- XHere is what C has that
- X.I perl
- Xdoesn't:
- X.Ip "unary &" 12
- XAddress-of operator.
- X.Ip "unary *" 12
- XDereference-address operator.
- X.Ip "(TYPE)" 12
- XType casting operator.
- X.PP
- XLike C,
- X.I perl
- Xdoes a certain amount of expression evaluation at compile time, whenever
- Xit determines that all of the arguments to an operator are static and have
- Xno side effects.
- XIn particular, string concatenation happens at compile time between literals that don't do variable substitution.
- XBackslash interpretation also happens at compile time.
- XYou can say
- X.nf
- X
- X.ne 2
- X \'Now is the time for all\' . "\|\e\|n" .
- X \'good men to come to.\'
- X
- X.fi
- Xand this all reduces to one string internally.
- X.PP
- XThe autoincrement operator has a little extra built-in magic to it.
- XIf you increment a variable that is numeric, or that has ever been used in
- Xa numeric context, you get a normal increment.
- XIf, however, the variable has only been used in string contexts since it
- Xwas set, and has a value that is not null and matches the
- Xpattern /^[a\-zA\-Z]*[0\-9]*$/, the increment is done
- Xas a string, preserving each character within its range, with carry:
- X.nf
- X
- X print ++($foo = \'99\'); # prints \*(L'100\*(R'
- X print ++($foo = \'a0\'); # prints \*(L'a1\*(R'
- X print ++($foo = \'Az\'); # prints \*(L'Ba\*(R'
- X print ++($foo = \'zz\'); # prints \*(L'aaa\*(R'
- X
- X.fi
- XThe autodecrement is not magical.
- !STUFFY!FUNK!
- echo Extracting t/op.exp
- sed >t/op.exp <<'!STUFFY!FUNK!' -e 's/X//'
- X#!./perl
- X
- X# $Header: op.exp,v 3.0 89/10/18 15:29:01 lwall Locked $
- X
- Xprint "1..6\n";
- X
- X# compile time evaluation
- X
- X$s = sqrt(2);
- Xif (substr($s,0,5) eq '1.414') {print "ok 1\n";} else {print "not ok 1\n";}
- X
- X$s = exp(1);
- Xif (substr($s,0,7) eq '2.71828') {print "ok 2\n";} else {print "not ok 2\n";}
- X
- Xif (exp(log(1)) == 1) {print "ok 3\n";} else {print "not ok 3\n";}
- X
- X# run time evaluation
- X
- X$x1 = 1;
- X$x2 = 2;
- X$s = sqrt($x2);
- Xif (substr($s,0,5) eq '1.414') {print "ok 4\n";} else {print "not ok 4\n";}
- X
- X$s = exp($x1);
- Xif (substr($s,0,7) eq '2.71828') {print "ok 5\n";} else {print "not ok 5\n";}
- X
- Xif (exp(log($x1)) == 1) {print "ok 6\n";} else {print "not ok 6\n";}
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 1 (of 24)"
- cat /dev/null >kit1isdone
- run=''
- config=''
- for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
- if test -f kit${iskit}isdone; then
- run="$run $iskit"
- else
- todo="$todo $iskit"
- fi
- done
- case $todo in
- '')
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- *) echo "You have run$run."
- echo "You still need to run$todo."
- ;;
- esac
- : Someone might mail this, so...
- exit
-
-