[comp.sources.misc] v18i028: perl - The perl programming language, Part10/36

lwall@netlabs.com (Larry Wall) (04/16/91)

Submitted-by: Larry Wall <lwall@netlabs.com>
Posting-number: Volume 18, Issue 28
Archive-name: perl/part10

[There are 36 kits for perl version 4.0.]

#! /bin/sh

# Make a new directory for the perl sources, cd to it, and run kits 1
# thru 36 through sh.  When all 36 kits have been run, read README.

echo "This is perl 4.0 kit 10 (of 36).  If kit 10 is complete, the line"
echo '"'"End of kit 10 (of 36)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir eg 2>/dev/null
echo Extracting perl.man:AD
sed >perl.man:AD <<'!STUFFY!FUNK!' -e 's/X//'
XNote that scalars are already passed by reference, so you can modify scalar
Xarguments without using this mechanism by referring explicitly to the $_[nnn]
Xin question.
XYou can modify all the elements of an array by passing all the elements
Xas scalars, but you have to use the * mechanism to push, pop or change the
Xsize of an array.
XThe * mechanism will probably be more efficient in any case.
X.Sp
XSince a *name value contains unprintable binary data, if it is used as
Xan argument in a print, or as a %s argument in a printf or sprintf, it
Xthen has the value '*name', just so it prints out pretty.
X.Sp
XEven if you don't want to modify an array, this mechanism is useful for
Xpassing multiple arrays in a single LIST, since normally the LIST mechanism
Xwill merge all the array values so that you can't extract out the
Xindividual arrays.
X.Sh "Regular Expressions"
XThe patterns used in pattern matching are regular expressions such as
Xthose supplied in the Version 8 regexp routines.
X(In fact, the routines are derived from Henry Spencer's freely redistributable
Xreimplementation of the V8 routines.)
XIn addition, \ew matches an alphanumeric character (including \*(L"_\*(R") and \eW a nonalphanumeric.
XWord boundaries may be matched by \eb, and non-boundaries by \eB.
XA whitespace character is matched by \es, non-whitespace by \eS.
XA numeric character is matched by \ed, non-numeric by \eD.
XYou may use \ew, \es and \ed within character classes.
XAlso, \en, \er, \ef, \et and \eNNN have their normal interpretations.
XWithin character classes \eb represents backspace rather than a word boundary.
XAlternatives may be separated by |.
XThe bracketing construct \|(\ .\|.\|.\ \|) may also be used, in which case \e<digit>
Xmatches the digit'th substring.
X(Outside of the pattern, always use $ instead of \e in front of the digit.
XThe scope of $<digit> (and $\`, $& and $\')
Xextends to the end of the enclosing BLOCK or eval string, or to
Xthe next pattern match with subexpressions.
XThe \e<digit> notation sometimes works outside the current pattern, but should
Xnot be relied upon.)
XYou may have as many parentheses as you wish.  If you have more than 9
Xsubstrings, the variables $10, $11, ... refer to the corresponding
Xsubstring.  Within the pattern, \e10, \e11,
Xetc. refer back to substrings if there have been at least that many left parens
Xbefore the backreference.  Otherwise (for backward compatibilty) \e10
Xis the same as \e010, a backspace,
Xand \e11 the same as \e011, a tab.
XAnd so on.
X(\e1 through \e9 are always backreferences.)
X.PP
X$+ returns whatever the last bracket match matched.
X$& returns the entire matched string.
X($0 used to return the same thing, but not any more.)
X$\` returns everything before the matched string.
X$\' returns everything after the matched string.
XExamples:
X.nf
X    
X	s/\|^\|([^ \|]*\|) \|*([^ \|]*\|)\|/\|$2 $1\|/;	# swap first two words
X
X.ne 5
X	if (/\|Time: \|(.\|.\|):\|(.\|.\|):\|(.\|.\|)\|/\|) {
X		$hours = $1;
X		$minutes = $2;
X		$seconds = $3;
X	}
X
X.fi
XBy default, the ^ character is only guaranteed to match at the beginning
Xof the string,
Xthe $ character only at the end (or before the newline at the end)
Xand
X.I perl
Xdoes certain optimizations with the assumption that the string contains
Xonly one line.
XThe behavior of ^ and $ on embedded newlines will be inconsistent.
XYou may, however, wish to treat a string as a multi-line buffer, such that
Xthe ^ will match after any newline within the string, and $ will match
Xbefore any newline.
XAt the cost of a little more overhead, you can do this by setting the variable
X$* to 1.
XSetting it back to 0 makes
X.I perl
Xrevert to its old behavior.
X.PP
XTo facilitate multi-line substitutions, the . character never matches a newline
X(even when $* is 0).
XIn particular, the following leaves a newline on the $_ string:
X.nf
X
X	$_ = <STDIN>;
X	s/.*(some_string).*/$1/;
X
XIf the newline is unwanted, try one of
X
X	s/.*(some_string).*\en/$1/;
X	s/.*(some_string)[^\e000]*/$1/;
X	s/.*(some_string)(.|\en)*/$1/;
X	chop; s/.*(some_string).*/$1/;
X	/(some_string)/ && ($_ = $1);
X
X.fi
XAny item of a regular expression may be followed with digits in curly brackets
Xof the form {n,m}, where n gives the minimum number of times to match the item
Xand m gives the maximum.
XThe form {n} is equivalent to {n,n} and matches exactly n times.
XThe form {n,} matches n or more times.
X(If a curly bracket occurs in any other context, it is treated as a regular
Xcharacter.)
XThe * modifier is equivalent to {0,}, the + modifier to {1,} and the ? modifier
Xto {0,1}.
XThere is no limit to the size of n or m, but large numbers will chew up
Xmore memory.
X.Sp
XYou will note that all backslashed metacharacters in
X.I perl
Xare alphanumeric,
Xsuch as \eb, \ew, \en.
XUnlike some other regular expression languages, there are no backslashed
Xsymbols that aren't alphanumeric.
XSo anything that looks like \e\e, \e(, \e), \e<, \e>, \e{, or \e} is always
Xinterpreted as a literal character, not a metacharacter.
XThis makes it simple to quote a string that you want to use for a pattern
Xbut that you are afraid might contain metacharacters.
XSimply quote all the non-alphanumeric characters:
X.nf
X
X	$pattern =~ s/(\eW)/\e\e$1/g;
X
X.fi
X.Sh "Formats"
XOutput record formats for use with the
X.I write
Xoperator may declared as follows:
X.nf
X
X.ne 3
X    format NAME =
X    FORMLIST
X    .
X
X.fi
XIf name is omitted, format \*(L"STDOUT\*(R" is defined.
XFORMLIST consists of a sequence of lines, each of which may be of one of three
Xtypes:
X.Ip 1. 4
XA comment.
X.Ip 2. 4
XA \*(L"picture\*(R" line giving the format for one output line.
X.Ip 3. 4
XAn argument line supplying values to plug into a picture line.
X.PP
XPicture lines are printed exactly as they look, except for certain fields
Xthat substitute values into the line.
XEach picture field starts with either @ or ^.
XThe @ field (not to be confused with the array marker @) is the normal
Xcase; ^ fields are used
Xto do rudimentary multi-line text block filling.
XThe length of the field is supplied by padding out the field
Xwith multiple <, >, or | characters to specify, respectively, left justification,
Xright justification, or centering.
XAs an alternate form of right justification,
Xyou may also use # characters (with an optional .) to specify a numeric field.
X(Use of ^ instead of @ causes the field to be blanked if undefined.)
XIf any of the values supplied for these fields contains a newline, only
Xthe text up to the newline is printed.
XThe special field @* can be used for printing multi-line values.
XIt should appear by itself on a line.
X.PP
XThe values are specified on the following line, in the same order as
Xthe picture fields.
XThe values should be separated by commas.
X.PP
XPicture fields that begin with ^ rather than @ are treated specially.
XThe value supplied must be a scalar variable name which contains a text
Xstring.
X.I Perl
Xputs as much text as it can into the field, and then chops off the front
Xof the string so that the next time the variable is referenced,
Xmore of the text can be printed.
XNormally you would use a sequence of fields in a vertical stack to print
Xout a block of text.
XIf you like, you can end the final field with .\|.\|., which will appear in the
Xoutput if the text was too long to appear in its entirety.
XYou can change which characters are legal to break on by changing the
Xvariable $: to a list of the desired characters.
X.PP
XSince use of ^ fields can produce variable length records if the text to be
Xformatted is short, you can suppress blank lines by putting the tilde (~)
Xcharacter anywhere in the line.
X(Normally you should put it in the front if possible, for visibility.)
XThe tilde will be translated to a space upon output.
XIf you put a second tilde contiguous to the first, the line will be repeated
Xuntil all the fields on the line are exhausted.
X(If you use a field of the @ variety, the expression you supply had better
Xnot give the same value every time forever!)
X.PP
XExamples:
X.nf
X.lg 0
X.cs R 25
X.ft C
X
X.ne 10
X# a report on the /etc/passwd file
Xformat top =
X\&                        Passwd File
XName                Login    Office   Uid   Gid Home
X------------------------------------------------------------------
X\&.
Xformat STDOUT =
X@<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<
X$name,              $login,  $office,$uid,$gid, $home
X\&.
X
X.ne 29
X# a report from a bug report form
Xformat top =
X\&                        Bug Reports
X@<<<<<<<<<<<<<<<<<<<<<<<     @|||         @>>>>>>>>>>>>>>>>>>>>>>>
X$system,                      $%,         $date
X------------------------------------------------------------------
X\&.
Xformat STDOUT =
XSubject: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&         $subject
XIndex: @<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&       $index,                       $description
XPriority: @<<<<<<<<<< Date: @<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&          $priority,        $date,   $description
XFrom: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&      $from,                         $description
XAssigned to: @<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&             $programmer,            $description
X\&~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&                                     $description
X\&~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&                                     $description
X\&~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&                                     $description
X\&~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X\&                                     $description
X\&~                                    ^<<<<<<<<<<<<<<<<<<<<<<<...
X\&                                     $description
X\&.
X
X.ft R
X.cs R
X.lg
X.fi
XIt is possible to intermix prints with writes on the same output channel,
Xbut you'll have to handle $\- (lines left on the page) yourself.
X.PP
XIf you are printing lots of fields that are usually blank, you should consider
Xusing the reset operator between records.
XNot only is it more efficient, but it can prevent the bug of adding another
Xfield and forgetting to zero it.
X.Sh "Interprocess Communication"
XThe IPC facilities of perl are built on the Berkeley socket mechanism.
XIf you don't have sockets, you can ignore this section.
XThe calls have the same names as the corresponding system calls,
Xbut the arguments tend to differ, for two reasons.
XFirst, perl file handles work differently than C file descriptors.
XSecond, perl already knows the length of its strings, so you don't need
Xto pass that information.
XHere is a sample client (untested):
X.nf
X
X	($them,$port) = @ARGV;
X	$port = 2345 unless $port;
X	$them = 'localhost' unless $them;
X
X	$SIG{'INT'} = 'dokill';
X	sub dokill { kill 9,$child if $child; }
X
X	require 'sys/socket.ph';
X
X	$sockaddr = 'S n a4 x8';
X	chop($hostname = `hostname`);
X
X	($name, $aliases, $proto) = getprotobyname('tcp');
X	($name, $aliases, $port) = getservbyname($port, 'tcp')
X		unless $port =~ /^\ed+$/;
X.ie t \{\
X	($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
X'br\}
X.el \{\
X	($name, $aliases, $type, $len, $thisaddr) =
X					gethostbyname($hostname);
X'br\}
X	($name, $aliases, $type, $len, $thataddr) = gethostbyname($them);
X
X	$this = pack($sockaddr, &AF_INET, 0, $thisaddr);
X	$that = pack($sockaddr, &AF_INET, $port, $thataddr);
X
X	socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
X	bind(S, $this) || die "bind: $!";
X	connect(S, $that) || die "connect: $!";
X
X	select(S); $| = 1; select(stdout);
X
X	if ($child = fork) {
X		while (<>) {
X			print S;
X		}
X		sleep 3;
X		do dokill();
X	}
X	else {
X		while (<S>) {
X			print;
X		}
X	}
X
X.fi
XAnd here's a server:
X.nf
X
X	($port) = @ARGV;
X	$port = 2345 unless $port;
X
X	require 'sys/socket.ph';
X
X	$sockaddr = 'S n a4 x8';
X
X	($name, $aliases, $proto) = getprotobyname('tcp');
X	($name, $aliases, $port) = getservbyname($port, 'tcp')
X		unless $port =~ /^\ed+$/;
X
X	$this = pack($sockaddr, &AF_INET, $port, "\e0\e0\e0\e0");
X
X	select(NS); $| = 1; select(stdout);
X
X	socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
X	bind(S, $this) || die "bind: $!";
X	listen(S, 5) || die "connect: $!";
X
X	select(S); $| = 1; select(stdout);
X
X	for (;;) {
X		print "Listening again\en";
X		($addr = accept(NS,S)) || die $!;
X		print "accept ok\en";
X
X		($af,$port,$inetaddr) = unpack($sockaddr,$addr);
X		@inetaddr = unpack('C4',$inetaddr);
X		print "$af $port @inetaddr\en";
X
X		while (<NS>) {
X			print;
X			print NS;
X		}
X	}
X
X.fi
X.Sh "Predefined Names"
XThe following names have special meaning to
X.IR perl .
XI could have used alphabetic symbols for some of these, but I didn't want
Xto take the chance that someone would say reset \*(L"a\-zA\-Z\*(R" and wipe them all
Xout.
XYou'll just have to suffer along with these silly symbols.
XMost of them have reasonable mnemonics, or analogues in one of the shells.
X.Ip $_ 8
XThe default input and pattern-searching space.
XThe following pairs are equivalent:
X.nf
X
X.ne 2
X	while (<>) {\|.\|.\|.	# only equivalent in while!
X	while ($_ = <>) {\|.\|.\|.
X
X.ne 2
X	/\|^Subject:/
X	$_ \|=~ \|/\|^Subject:/
X
X.ne 2
X	y/a\-z/A\-Z/
X	$_ =~ y/a\-z/A\-Z/
X
X.ne 2
X	chop
X	chop($_)
X
X.fi 
X(Mnemonic: underline is understood in certain operations.)
X.Ip $. 8
XThe current input line number of the last filehandle that was read.
XReadonly.
XRemember that only an explicit close on the filehandle resets the line number.
XSince <> never does an explicit close, line numbers increase across ARGV files
X(but see examples under eof).
X(Mnemonic: many programs use . to mean the current line number.)
X.Ip $/ 8
XThe input record separator, newline by default.
XWorks like
X.IR awk 's
XRS variable, including treating blank lines as delimiters
Xif set to the null string.
XYou may set it to a multicharacter string to match a multi-character
Xdelimiter.
X(Mnemonic: / is used to delimit line boundaries when quoting poetry.)
X.Ip $, 8
XThe output field separator for the print operator.
XOrdinarily the print operator simply prints out the comma separated fields
Xyou specify.
XIn order to get behavior more like
X.IR awk ,
Xset this variable as you would set
X.IR awk 's
XOFS variable to specify what is printed between fields.
X(Mnemonic: what is printed when there is a , in your print statement.)
X.Ip $"" 8
XThis is like $, except that it applies to array values interpolated into
Xa double-quoted string (or similar interpreted string).
XDefault is a space.
X(Mnemonic: obvious, I think.)
X.Ip $\e 8
XThe output record separator for the print operator.
XOrdinarily the print operator simply prints out the comma separated fields
Xyou specify, with no trailing newline or record separator assumed.
XIn order to get behavior more like
X.IR awk ,
Xset this variable as you would set
X.IR awk 's
XORS variable to specify what is printed at the end of the print.
X(Mnemonic: you set $\e instead of adding \en at the end of the print.
XAlso, it's just like /, but it's what you get \*(L"back\*(R" from
X.IR perl .)
X.Ip $# 8
XThe output format for printed numbers.
XThis variable is a half-hearted attempt to emulate
X.IR awk 's
XOFMT variable.
XThere are times, however, when
X.I awk
Xand
X.I perl
Xhave differing notions of what
Xis in fact numeric.
XAlso, the initial value is %.20g rather than %.6g, so you need to set $#
Xexplicitly to get
X.IR awk 's
Xvalue.
X(Mnemonic: # is the number sign.)
X.Ip $% 8
XThe current page number of the currently selected output channel.
X(Mnemonic: % is page number in nroff.)
X.Ip $= 8
XThe current page length (printable lines) of the currently selected output
Xchannel.
XDefault is 60.
X(Mnemonic: = has horizontal lines.)
X.Ip $\- 8
XThe number of lines left on the page of the currently selected output channel.
X(Mnemonic: lines_on_page \- lines_printed.)
X.Ip $~ 8
XThe name of the current report format for the currently selected output
Xchannel.
X(Mnemonic: brother to $^.)
X.Ip $^ 8
XThe name of the current top-of-page format for the currently selected output
Xchannel.
X(Mnemonic: points to top of page.)
X.Ip $| 8
XIf set to nonzero, forces a flush after every write or print on the currently
Xselected output channel.
XDefault is 0.
XNote that
X.I STDOUT
Xwill typically be line buffered if output is to the
Xterminal and block buffered otherwise.
XSetting this variable is useful primarily when you are outputting to a pipe,
Xsuch as when you are running a
X.I perl
Xscript under rsh and want to see the
Xoutput as it's happening.
X(Mnemonic: when you want your pipes to be piping hot.)
X.Ip $$ 8
XThe process number of the
X.I perl
Xrunning this script.
X(Mnemonic: same as shells.)
X.Ip $? 8
XThe status returned by the last pipe close, backtick (\`\`) command or
X.I system
Xoperator.
XNote that this is the status word returned by the wait() system
Xcall, so the exit value of the subprocess is actually ($? >> 8).
X$? & 255 gives which signal, if any, the process died from, and whether
Xthere was a core dump.
X(Mnemonic: similar to sh and ksh.)
X.Ip $& 8 4
XThe string matched by the last pattern match (not counting any matches hidden
Xwithin a BLOCK or eval enclosed by the current BLOCK).
X(Mnemonic: like & in some editors.)
X.Ip $\` 8 4
XThe string preceding whatever was matched by the last pattern match
X(not counting any matches hidden within a BLOCK or eval enclosed by the current
XBLOCK).
X(Mnemonic: \` often precedes a quoted string.)
X.Ip $\' 8 4
XThe string following whatever was matched by the last pattern match
X(not counting any matches hidden within a BLOCK or eval enclosed by the current
XBLOCK).
X(Mnemonic: \' often follows a quoted string.)
XExample:
X.nf
X
X.ne 3
X	$_ = \'abcdefghi\';
X	/def/;
X	print "$\`:$&:$\'\en";  	# prints abc:def:ghi
X
X.fi
X.Ip $+ 8 4
XThe last bracket matched by the last search pattern.
XThis is useful if you don't know which of a set of alternative patterns
Xmatched.
XFor example:
X.nf
X
X    /Version: \|(.*\|)|Revision: \|(.*\|)\|/ \|&& \|($rev = $+);
X
X.fi
X(Mnemonic: be positive and forward looking.)
X.Ip $* 8 2
XSet to 1 to do multiline matching within a string, 0 to tell
X.I perl
Xthat it can assume that strings contain a single line, for the purpose
Xof optimizing pattern matches.
XPattern matches on strings containing multiple newlines can produce confusing
Xresults when $* is 0.
XDefault is 0.
X(Mnemonic: * matches multiple things.)
XNote that this variable only influences the interpretation of ^ and $.
XA literal newline can be searched for even when $* == 0.
X.Ip $0 8
XContains the name of the file containing the
X.I perl
Xscript being executed.
XAssigning to $0 modifies the argument area that the ps(1) program sees.
X(Mnemonic: same as sh and ksh.)
X.Ip $<digit> 8
XContains the subpattern from the corresponding set of parentheses in the last
Xpattern matched, not counting patterns matched in nested blocks that have
Xbeen exited already.
X(Mnemonic: like \edigit.)
X.Ip $[ 8 2
XThe index of the first element in an array, and of the first character in
Xa substring.
XDefault is 0, but you could set it to 1 to make
X.I perl
Xbehave more like
X.I awk
X(or Fortran)
Xwhen subscripting and when evaluating the index() and substr() functions.
X(Mnemonic: [ begins subscripts.)
X.Ip $] 8 2
XThe string printed out when you say \*(L"perl -v\*(R".
XIt can be used to determine at the beginning of a script whether the perl
Xinterpreter executing the script is in the right range of versions.
XIf used in a numeric context, returns the version + patchlevel / 1000.
XExample:
X.nf
X
X.ne 8
X	# see if getc is available
X        ($version,$patchlevel) =
X		 $] =~ /(\ed+\e.\ed+).*\enPatch level: (\ed+)/;
X        print STDERR "(No filename completion available.)\en"
X		 if $version * 1000 + $patchlevel < 2016;
X
Xor, used numerically,
X
X	warn "No checksumming!\en" if $] < 3.019;
X
X.fi
X(Mnemonic: Is this version of perl in the right bracket?)
X.Ip $; 8 2
XThe subscript separator for multi-dimensional array emulation.
XIf you refer to an associative array element as
X.nf
X	$foo{$a,$b,$c}
X
Xit really means
X
X	$foo{join($;, $a, $b, $c)}
X
XBut don't put
X
X	@foo{$a,$b,$c}		# a slice\*(--note the @
X
Xwhich means
X
X	($foo{$a},$foo{$b},$foo{$c})
X
X.fi
XDefault is "\e034", the same as SUBSEP in
X.IR awk .
XNote that if your keys contain binary data there might not be any safe
Xvalue for $;.
X(Mnemonic: comma (the syntactic subscript separator) is a semi-semicolon.
XYeah, I know, it's pretty lame, but $, is already taken for something more
Ximportant.)
X.Ip $! 8 2
XIf used in a numeric context, yields the current value of errno, with all the
Xusual caveats.
X(This means that you shouldn't depend on the value of $! to be anything
Xin particular unless you've gotten a specific error return indicating a
Xsystem error.)
XIf used in a string context, yields the corresponding system error string.
XYou can assign to $! in order to set errno
Xif, for instance, you want $! to return the string for error n, or you want
Xto set the exit value for the die operator.
X(Mnemonic: What just went bang?)
X.Ip $@ 8 2
XThe perl syntax error message from the last eval command.
XIf null, the last eval parsed and executed correctly (although the operations
Xyou invoked may have failed in the normal fashion).
X(Mnemonic: Where was the syntax error \*(L"at\*(R"?)
X.Ip $< 8 2
XThe real uid of this process.
X(Mnemonic: it's the uid you came FROM, if you're running setuid.)
X.Ip $> 8 2
XThe effective uid of this process.
XExample:
X.nf
X
X.ne 2
X	$< = $>;	# set real uid to the effective uid
X	($<,$>) = ($>,$<);	# swap real and effective uid
X
X.fi
X(Mnemonic: it's the uid you went TO, if you're running setuid.)
XNote: $< and $> can only be swapped on machines supporting setreuid().
X.Ip $( 8 2
XThe real gid of this process.
XIf you are on a machine that supports membership in multiple groups
Xsimultaneously, gives a space separated list of groups you are in.
XThe first number is the one returned by getgid(), and the subsequent ones
Xby getgroups(), one of which may be the same as the first number.
X(Mnemonic: parentheses are used to GROUP things.
XThe real gid is the group you LEFT, if you're running setgid.)
X.Ip $) 8 2
XThe effective gid of this process.
XIf you are on a machine that supports membership in multiple groups
Xsimultaneously, gives a space separated list of groups you are in.
XThe first number is the one returned by getegid(), and the subsequent ones
Xby getgroups(), one of which may be the same as the first number.
X(Mnemonic: parentheses are used to GROUP things.
XThe effective gid is the group that's RIGHT for you, if you're running setgid.)
X.Sp
XNote: $<, $>, $( and $) can only be set on machines that support the
Xcorresponding set[re][ug]id() routine.
X$( and $) can only be swapped on machines supporting setregid().
X.Ip $: 8 2
XThe current set of characters after which a string may be broken to
Xfill continuation fields (starting with ^) in a format.
XDefault is "\ \en-", to break on whitespace or hyphens.
X(Mnemonic: a \*(L"colon\*(R" in poetry is a part of a line.)
X.Ip $^D 8 2
XThe current value of the debugging flags.
X(Mnemonic: value of
X.B \-D
Xswitch.)
X.Ip $^I 8 2
XThe current value of the inplace-edit extension.
XUse undef to disable inplace editing.
X(Mnemonic: value of
X.B \-i
Xswitch.)
X.Ip $^P 8 2
XThe name that Perl itself was invoked as, from argv[0].
X.Ip $^T 8 2
XThe time at which the script began running, in seconds since the epoch.
XThe values returned by the
X.B \-M ,
X.B \-A
Xand
X.B \-C
Xfiletests are based on this value.
X.Ip $^W 8 2
XThe current value of the warning switch.
X(Mnemonic: related to the
X.B \-w
Xswitch.)
X.Ip $ARGV 8 3
Xcontains the name of the current file when reading from <>.
X.Ip @ARGV 8 3
XThe array ARGV contains the command line arguments intended for the script.
XNote that $#ARGV is the generally number of arguments minus one, since
X$ARGV[0] is the first argument, NOT the command name.
XSee $0 for the command name.
X.Ip @INC 8 3
XThe array INC contains the list of places to look for
X.I perl
Xscripts to be
Xevaluated by the \*(L"do EXPR\*(R" command or the \*(L"require\*(R" command.
XIt initially consists of the arguments to any
X.B \-I
Xcommand line switches, followed
Xby the default
X.I perl
Xlibrary, probably \*(L"/usr/local/lib/perl\*(R",
Xfollowed by \*(L".\*(R", to represent the current directory.
X.Ip %INC 8 3
XThe associative array INC contains entries for each filename that has
Xbeen included via \*(L"do\*(R" or \*(L"require\*(R".
XThe key is the filename you specified, and the value is the location of
Xthe file actually found.
XThe \*(L"require\*(R" command uses this array to determine whether
Xa given file has already been included.
X.Ip $ENV{expr} 8 2
XThe associative array ENV contains your current environment.
XSetting a value in ENV changes the environment for child processes.
X.Ip $SIG{expr} 8 2
XThe associative array SIG is used to set signal handlers for various signals.
XExample:
X.nf
X
X.ne 12
X	sub handler {	# 1st argument is signal name
X		local($sig) = @_;
X		print "Caught a SIG$sig\-\|\-shutting down\en";
X		close(LOG);
X		exit(0);
X	}
X
X	$SIG{\'INT\'} = \'handler\';
X	$SIG{\'QUIT\'} = \'handler\';
X	.\|.\|.
X	$SIG{\'INT\'} = \'DEFAULT\';	# restore default action
X	$SIG{\'QUIT\'} = \'IGNORE\';	# ignore SIGQUIT
X
X.fi
XThe SIG array only contains values for the signals actually set within
Xthe perl script.
X.Sh "Packages"
XPerl provides a mechanism for alternate namespaces to protect packages from
Xstomping on each others variables.
XBy default, a perl script starts compiling into the package known as \*(L"main\*(R".
XBy use of the
X.I package
Xdeclaration, you can switch namespaces.
XThe scope of the package declaration is from the declaration itself to the end
Xof the enclosing block (the same scope as the local() operator).
XTypically it would be the first declaration in a file to be included by
Xthe \*(L"require\*(R" operator.
XYou can switch into a package in more than one place; it merely influences
Xwhich symbol table is used by the compiler for the rest of that block.
XYou can refer to variables and filehandles in other packages by prefixing
Xthe identifier with the package name and a single quote.
XIf the package name is null, the \*(L"main\*(R" package as assumed.
X.PP
XOnly identifiers starting with letters are stored in the packages symbol
Xtable.
XAll other symbols are kept in package \*(L"main\*(R".
XIn addition, the identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC
Xand SIG are forced to be in package \*(L"main\*(R", even when used for
Xother purposes than their built-in one.
XNote also that, if you have a package called \*(L"m\*(R", \*(L"s\*(R"
Xor \*(L"y\*(R", the you can't use the qualified form of an identifier since it
Xwill be interpreted instead as a pattern match, a substitution
Xor a translation.
X.PP
XEval'ed strings are compiled in the package in which the eval was compiled
Xin.
X(Assignments to $SIG{}, however, assume the signal handler specified is in the
Xmain package.
XQualify the signal handler name if you wish to have a signal handler in
Xa package.)
XFor an example, examine perldb.pl in the perl library.
XIt initially switches to the DB package so that the debugger doesn't interfere
Xwith variables in the script you are trying to debug.
XAt various points, however, it temporarily switches back to the main package
Xto evaluate various expressions in the context of the main package.
X.PP
XThe symbol table for a package happens to be stored in the associative array
Xof that name prepended with an underscore.
XThe value in each entry of the associative array is
Xwhat you are referring to when you use the *name notation.
XIn fact, the following have the same effect (in package main, anyway),
Xthough the first is more
Xefficient because it does the symbol table lookups at compile time:
X.nf
X
X.ne 2
X	local(*foo) = *bar;
X	local($_main{'foo'}) = $_main{'bar'};
X
X.fi
XYou can use this to print out all the variables in a package, for instance.
XHere is dumpvar.pl from the perl library:
X.nf
X.ne 11
X	package dumpvar;
X
X	sub main'dumpvar {
X	\&    ($package) = @_;
X	\&    local(*stab) = eval("*_$package");
X	\&    while (($key,$val) = each(%stab)) {
X	\&        {
X	\&            local(*entry) = $val;
X	\&            if (defined $entry) {
X	\&                print "\e$$key = '$entry'\en";
X	\&            }
X.ne 7
X	\&            if (defined @entry) {
X	\&                print "\e@$key = (\en";
X	\&                foreach $num ($[ .. $#entry) {
X	\&                    print "  $num\et'",$entry[$num],"'\en";
X	\&                }
X	\&                print ")\en";
X	\&            }
X.ne 10
X	\&            if ($key ne "_$package" && defined %entry) {
X	\&                print "\e%$key = (\en";
X	\&                foreach $key (sort keys(%entry)) {
X	\&                    print "  $key\et'",$entry{$key},"'\en";
X	\&                }
X	\&                print ")\en";
X	\&            }
X	\&        }
X	\&    }
X	}
X
X.fi
XNote that, even though the subroutine is compiled in package dumpvar, the
Xname of the subroutine is qualified so that its name is inserted into package
X\*(L"main\*(R".
X.Sh "Style"
XEach programmer will, of course, have his or her own preferences in regards
Xto formatting, but there are some general guidelines that will make your
Xprograms easier to read.
X.Ip 1. 4 4
XJust because you CAN do something a particular way doesn't mean that
Xyou SHOULD do it that way.
X.I Perl
Xis designed to give you several ways to do anything, so consider picking
Xthe most readable one.
XFor instance
X
X	open(FOO,$foo) || die "Can't open $foo: $!";
X
Xis better than
X
X	die "Can't open $foo: $!" unless open(FOO,$foo);
X
Xbecause the second way hides the main point of the statement in a
Xmodifier.
XOn the other hand
X
X	print "Starting analysis\en" if $verbose;
X
Xis better than
X
X	$verbose && print "Starting analysis\en";
X
Xsince the main point isn't whether the user typed -v or not.
X.Sp
XSimilarly, just because an operator lets you assume default arguments
Xdoesn't mean that you have to make use of the defaults.
XThe defaults are there for lazy systems programmers writing one-shot
Xprograms.
XIf you want your program to be readable, consider supplying the argument.
X.Sp
XAlong the same lines, just because you
X.I can
Xomit parentheses in many places doesn't mean that you ought to:
X.nf
X
X	return print reverse sort num values array;
X	return print(reverse(sort num (values(%array))));
X
X.fi
XWhen in doubt, parenthesize.
XAt the very least it will let some poor schmuck bounce on the % key in vi.
X.Sp
XEven if you aren't in doubt, consider the mental welfare of the person who
Xhas to maintain the code after you, and who will probably put parens in
Xthe wrong place.
X.Ip 2. 4 4
XDon't go through silly contortions to exit a loop at the top or the
Xbottom, when
X.I perl
Xprovides the "last" operator so you can exit in the middle.
XJust outdent it a little to make it more visible:
X.nf
X
X.ne 7
X    line:
X	for (;;) {
X	    statements;
X	last line if $foo;
X	    next line if /^#/;
X	    statements;
X	}
X
X.fi
X.Ip 3. 4 4
XDon't be afraid to use loop labels\*(--they're there to enhance readability as
Xwell as to allow multi-level loop breaks.
XSee last example.
X.Ip 4. 4 4
XFor portability, when using features that may not be implemented on every
Xmachine, test the construct in an eval to see if it fails.
XIf you know what version or patchlevel a particular feature was implemented,
Xyou can test $] to see if it will be there.
X.Ip 5. 4 4
XChoose mnemonic identifiers.
X.Ip 6. 4 4
XBe consistent.
X.Sh "Debugging"
XIf you invoke
X.I perl
Xwith a
X.B \-d
Xswitch, your script will be run under a debugging monitor.
XIt will halt before the first executable statement and ask you for a
Xcommand, such as:
X.Ip "h" 12 4
XPrints out a help message.
X.Ip "T" 12 4
XStack trace.
X.Ip "s" 12 4
XSingle step.
XExecutes until it reaches the beginning of another statement.
X.Ip "n" 12 4
XNext.
XExecutes over subroutine calls, until it reaches the beginning of the 
Xnext statement.
X.Ip "f" 12 4
XFinish.
XExecutes statements until it has finished the current subroutine.
X.Ip "c" 12 4
XContinue.
XExecutes until the next breakpoint is reached.
X.Ip "c line" 12 4
XContinue to the specified line.
XInserts a one-time-only breakpoint at the specified line.
X.Ip "<CR>" 12 4
XRepeat last n or s.
X.Ip "l min+incr" 12 4
XList incr+1 lines starting at min.
XIf min is omitted, starts where last listing left off.
XIf incr is omitted, previous value of incr is used.
X.Ip "l min-max" 12 4
XList lines in the indicated range.
X.Ip "l line" 12 4
XList just the indicated line.
X.Ip "l" 12 4
XList next window.
X.Ip "-" 12 4
XList previous window.
X.Ip "w line" 12 4
XList window around line.
X.Ip "l subname" 12 4
XList subroutine.
XIf it's a long subroutine it just lists the beginning.
XUse \*(L"l\*(R" to list more.
X.Ip "/pattern/" 12 4
XRegular expression search forward for pattern; the final / is optional.
X.Ip "?pattern?" 12 4
XRegular expression search backward for pattern; the final ? is optional.
X.Ip "L" 12 4
XList lines that have breakpoints or actions.
X.Ip "S" 12 4
XLists the names of all subroutines.
X.Ip "t" 12 4
XToggle trace mode on or off.
X.Ip "b line condition" 12 4
XSet a breakpoint.
XIf line is omitted, sets a breakpoint on the 
Xline that is about to be executed.
XIf a condition is specified, it is evaluated each time the statement is
Xreached and a breakpoint is taken only if the condition is true.
XBreakpoints may only be set on lines that begin an executable statement.
X.Ip "b subname condition" 12 4
XSet breakpoint at first executable line of subroutine.
X.Ip "d line" 12 4
XDelete breakpoint.
XIf line is omitted, deletes the breakpoint on the 
Xline that is about to be executed.
X.Ip "D" 12 4
XDelete all breakpoints.
X.Ip "a line command" 12 4
XSet an action for line.
XA multi-line command may be entered by backslashing the newlines.
X.Ip "A" 12 4
XDelete all line actions.
X.Ip "< command" 12 4
XSet an action to happen before every debugger prompt.
XA multi-line command may be entered by backslashing the newlines.
X.Ip "> command" 12 4
XSet an action to happen after the prompt when you've just given a command
Xto return to executing the script.
XA multi-line command may be entered by backslashing the newlines.
X.Ip "V package" 12 4
XList all variables in package.
XDefault is main package.
X.Ip "! number" 12 4
XRedo a debugging command.
XIf number is omitted, redoes the previous command.
X.Ip "! -number" 12 4
XRedo the command that was that many commands ago.
X.Ip "H -number" 12 4
XDisplay last n commands.
XOnly commands longer than one character are listed.
XIf number is omitted, lists them all.
X.Ip "q or ^D" 12 4
XQuit.
X.Ip "command" 12 4
XExecute command as a perl statement.
XA missing semicolon will be supplied.
X.Ip "p expr" 12 4
XSame as \*(L"print DB'OUT expr\*(R".
XThe DB'OUT filehandle is opened to /dev/tty, regardless of where STDOUT
Xmay be redirected to.
X.PP
XIf you want to modify the debugger, copy perldb.pl from the perl library
Xto your current directory and modify it as necessary.
X(You'll also have to put -I. on your command line.)
XYou can do some customization by setting up a .perldb file which contains
Xinitialization code.
XFor instance, you could make aliases like these:
X.nf
X
X    $DB'alias{'len'} = 's/^len(.*)/p length($1)/';
X    $DB'alias{'stop'} = 's/^stop (at|in)/b/';
X    $DB'alias{'.'} =
X      's/^\e./p "\e$DB\e'sub(\e$DB\e'line):\et",\e$DB\e'line[\e$DB\e'line]/';
X
X.fi
X.Sh "Setuid Scripts"
X.I Perl
Xis designed to make it easy to write secure setuid and setgid scripts.
XUnlike shells, which are based on multiple substitution passes on each line
Xof the script,
X.I perl
Xuses a more conventional evaluation scheme with fewer hidden \*(L"gotchas\*(R".
XAdditionally, since the language has more built-in functionality, it
Xhas to rely less upon external (and possibly untrustworthy) programs to
Xaccomplish its purposes.
X.PP
XIn an unpatched 4.2 or 4.3bsd kernel, setuid scripts are intrinsically
Xinsecure, but this kernel feature can be disabled.
XIf it is,
X.I perl
Xcan emulate the setuid and setgid mechanism when it notices the otherwise
Xuseless setuid/gid bits on perl scripts.
XIf the kernel feature isn't disabled,
X.I perl
Xwill complain loudly that your setuid script is insecure.
XYou'll need to either disable the kernel setuid script feature, or put
Xa C wrapper around the script.
X.PP
XWhen perl is executing a setuid script, it takes special precautions to
Xprevent you from falling into any obvious traps.
X(In some ways, a perl script is more secure than the corresponding
XC program.)
XAny command line argument, environment variable, or input is marked as
X\*(L"tainted\*(R", and may not be used, directly or indirectly, in any
Xcommand that invokes a subshell, or in any command that modifies files,
Xdirectories or processes.
XAny variable that is set within an expression that has previously referenced
Xa tainted value also becomes tainted (even if it is logically impossible
Xfor the tainted value to influence the variable).
XFor example:
X.nf
X
X.ne 5
X	$foo = shift;			# $foo is tainted
X	$bar = $foo,\'bar\';		# $bar is also tainted
X	$xxx = <>;			# Tainted
X	$path = $ENV{\'PATH\'};	# Tainted, but see below
X	$abc = \'abc\';			# Not tainted
X
X.ne 4
X	system "echo $foo";		# Insecure
X	system "/bin/echo", $foo;	# Secure (doesn't use sh)
X	system "echo $bar";		# Insecure
X	system "echo $abc";		# Insecure until PATH set
X
X.ne 5
X	$ENV{\'PATH\'} = \'/bin:/usr/bin\';
X	$ENV{\'IFS\'} = \'\' if $ENV{\'IFS\'} ne \'\';
X
X	$path = $ENV{\'PATH\'};	# Not tainted
X	system "echo $abc";		# Is secure now!
X
X.ne 5
X	open(FOO,"$foo");		# OK
X	open(FOO,">$foo"); 		# Not OK
X
X	open(FOO,"echo $foo|");	# Not OK, but...
X	open(FOO,"-|") || exec \'echo\', $foo;	# OK
X
X	$zzz = `echo $foo`;		# Insecure, zzz tainted
X
X	unlink $abc,$foo;		# Insecure
X	umask $foo;			# Insecure
X
X.ne 3
X	exec "echo $foo";		# Insecure
X	exec "echo", $foo;		# Secure (doesn't use sh)
X	exec "sh", \'-c\', $foo;	# Considered secure, alas
X
X.fi
XThe taintedness is associated with each scalar value, so some elements
Xof an array can be tainted, and others not.
X.PP
XIf you try to do something insecure, you will get a fatal error saying 
Xsomething like \*(L"Insecure dependency\*(R" or \*(L"Insecure PATH\*(R".
XNote that you can still write an insecure system call or exec,
Xbut only by explicitly doing something like the last example above.
XYou can also bypass the tainting mechanism by referencing
Xsubpatterns\*(--\c
X.I perl
Xpresumes that if you reference a substring using $1, $2, etc, you knew
Xwhat you were doing when you wrote the pattern:
X.nf
X
X	$ARGV[0] =~ /^\-P(\ew+)$/;
X	$printer = $1;		# Not tainted
X
X.fi
XThis is fairly secure since \ew+ doesn't match shell metacharacters.
XUse of .+ would have been insecure, but
X.I perl
Xdoesn't check for that, so you must be careful with your patterns.
XThis is the ONLY mechanism for untainting user supplied filenames if you
Xwant to do file operations on them (unless you make $> equal to $<).
X.PP
XIt's also possible to get into trouble with other operations that don't care
Xwhether they use tainted values.
XMake judicious use of the file tests in dealing with any user-supplied
Xfilenames.
XWhen possible, do opens and such after setting $> = $<.
X.I Perl
Xdoesn't prevent you from opening tainted filenames for reading, so be
Xcareful what you print out.
XThe tainting mechanism is intended to prevent stupid mistakes, not to remove
Xthe need for thought.
X.SH ENVIRONMENT
X.I Perl
Xuses PATH in executing subprocesses, and in finding the script if \-S
Xis used.
XHOME or LOGDIR are used if chdir has no argument.
X.PP
XApart from these,
X.I perl
Xuses no environment variables, except to make them available
Xto the script being executed, and to child processes.
XHowever, scripts running setuid would do well to execute the following lines
Xbefore doing anything else, just to keep people honest:
X.nf
X
X.ne 3
X    $ENV{\'PATH\'} = \'/bin:/usr/bin\';    # or whatever you need
X    $ENV{\'SHELL\'} = \'/bin/sh\' if $ENV{\'SHELL\'} ne \'\';
X    $ENV{\'IFS\'} = \'\' if $ENV{\'IFS\'} ne \'\';
X
X.fi
X.SH AUTHOR
XLarry Wall <lwall@jpl-devvax.Jpl.Nasa.Gov>
X.br
XMS-DOS port by Diomidis Spinellis <dds@cc.ic.ac.uk>
X.SH FILES
X/tmp/perl\-eXXXXXX	temporary file for
X.B \-e
Xcommands.
X.SH SEE ALSO
Xa2p	awk to perl translator
X.br
Xs2p	sed to perl translator
X.SH DIAGNOSTICS
XCompilation errors will tell you the line number of the error, with an
Xindication of the next token or token type that was to be examined.
X(In the case of a script passed to
X.I perl
Xvia
X.B \-e
Xswitches, each
X.B \-e
Xis counted as one line.)
X.PP
XSetuid scripts have additional constraints that can produce error messages
Xsuch as \*(L"Insecure dependency\*(R".
XSee the section on setuid scripts.
X.SH TRAPS
XAccustomed
X.IR awk
Xusers should take special note of the following:
X.Ip * 4 2
XSemicolons are required after all simple statements in
X.IR perl .
XNewline
Xis not a statement delimiter.
X.Ip * 4 2
XCurly brackets are required on ifs and whiles.
X.Ip * 4 2
XVariables begin with $ or @ in
X.IR perl .
X.Ip * 4 2
XArrays index from 0 unless you set $[.
XLikewise string positions in substr() and index().
X.Ip * 4 2
XYou have to decide whether your array has numeric or string indices.
X.Ip * 4 2
XAssociative array values do not spring into existence upon mere reference.
X.Ip * 4 2
XYou have to decide whether you want to use string or numeric comparisons.
X.Ip * 4 2
XReading an input line does not split it for you.  You get to split it yourself
Xto an array.
XAnd the
X.I split
Xoperator has different arguments.
X.Ip * 4 2
XThe current input line is normally in $_, not $0.
XIt generally does not have the newline stripped.
X($0 is the name of the program executed.)
X.Ip * 4 2
X$<digit> does not refer to fields\*(--it refers to substrings matched by the last
Xmatch pattern.
X.Ip * 4 2
XThe
X.I print
Xstatement does not add field and record separators unless you set
X$, and $\e.
X.Ip * 4 2
XYou must open your files before you print to them.
X.Ip * 4 2
XThe range operator is \*(L".\|.\*(R", not comma.
X(The comma operator works as in C.)
X.Ip * 4 2
XThe match operator is \*(L"=~\*(R", not \*(L"~\*(R".
X(\*(L"~\*(R" is the one's complement operator, as in C.)
X.Ip * 4 2
XThe exponentiation operator is \*(L"**\*(R", not \*(L"^\*(R".
X(\*(L"^\*(R" is the XOR operator, as in C.)
X.Ip * 4 2
XThe concatenation operator is \*(L".\*(R", not the null string.
X(Using the null string would render \*(L"/pat/ /pat/\*(R" unparsable,
Xsince the third slash would be interpreted as a division operator\*(--the
Xtokener is in fact slightly context sensitive for operators like /, ?, and <.
XAnd in fact, . itself can be the beginning of a number.)
X.Ip * 4 2
X.IR Next ,
X.I exit
Xand
X.I continue
Xwork differently.
X.Ip * 4 2
XThe following variables work differently
X.nf
X
X	  Awk	\h'|2.5i'Perl
X	  ARGC	\h'|2.5i'$#ARGV
X	  ARGV[0]	\h'|2.5i'$0
X	  FILENAME\h'|2.5i'$ARGV
X	  FNR	\h'|2.5i'$. \- something
X	  FS	\h'|2.5i'(whatever you like)
X	  NF	\h'|2.5i'$#Fld, or some such
X	  NR	\h'|2.5i'$.
X	  OFMT	\h'|2.5i'$#
X	  OFS	\h'|2.5i'$,
X	  ORS	\h'|2.5i'$\e
X	  RLENGTH	\h'|2.5i'length($&)
X	  RS	\h'|2.5i'$/
X	  RSTART	\h'|2.5i'length($\`)
X	  SUBSEP	\h'|2.5i'$;
X
X.fi
X.Ip * 4 2
XWhen in doubt, run the
X.I awk
Xconstruct through a2p and see what it gives you.
X.PP
XCerebral C programmers should take note of the following:
X.Ip * 4 2
XCurly brackets are required on ifs and whiles.
X.Ip * 4 2
XYou should use \*(L"elsif\*(R" rather than \*(L"else if\*(R"
X.Ip * 4 2
X.I Break
Xand
X.I continue
Xbecome
X.I last
Xand
X.IR next ,
Xrespectively.
X.Ip * 4 2
XThere's no switch statement.
X.Ip * 4 2
XVariables begin with $ or @ in
X.IR perl .
X.Ip * 4 2
XPrintf does not implement *.
X.Ip * 4 2
XComments begin with #, not /*.
X.Ip * 4 2
XYou can't take the address of anything.
X.Ip * 4 2
XARGV must be capitalized.
X.Ip * 4 2
XThe \*(L"system\*(R" calls link, unlink, rename, etc. return nonzero for success, not 0.
X.Ip * 4 2
XSignal handlers deal with signal names, not numbers.
X.PP
XSeasoned
X.I sed
Xprogrammers should take note of the following:
X.Ip * 4 2
XBackreferences in substitutions use $ rather than \e.
X.Ip * 4 2
XThe pattern matching metacharacters (, ), and | do not have backslashes in front.
X.Ip * 4 2
XThe range operator is .\|. rather than comma.
X.PP
XSharp shell programmers should take note of the following:
X.Ip * 4 2
XThe backtick operator does variable interpretation without regard to the
Xpresence of single quotes in the command.
X.Ip * 4 2
XThe backtick operator does no translation of the return value, unlike csh.
X.Ip * 4 2
XShells (especially csh) do several levels of substitution on each command line.
X.I Perl
Xdoes substitution only in certain constructs such as double quotes,
Xbackticks, angle brackets and search patterns.
X.Ip * 4 2
XShells interpret scripts a little bit at a time.
X.I Perl
Xcompiles the whole program before executing it.
X.Ip * 4 2
XThe arguments are available via @ARGV, not $1, $2, etc.
X.Ip * 4 2
XThe environment is not automatically made available as variables.
X.SH ERRATA\0AND\0ADDENDA
XThe Perl book,
X.I Programming\0Perl ,
Xhas the following omissions and goofs.
X.PP
XOn page 5, the examples which read
X.nf
X
X	eval "/usr/bin/perl
X
Xshould read
X
X	eval "exec /usr/bin/perl
X
X.fi
X.PP
XOn page 195, the equivalent to the System V sum program only works for
Xvery small files.  To do larger files, use
X.nf
X
X	undef $/;
X	$checksum = unpack("%32C*",<>) % 32767;
X
X.fi
X.PP
XThe
X.B \-0
Xswitch to set the initial value of $/ was added to Perl after the book
Xwent to press.
X.PP
XThe
X.B \-l
Xswitch now does automatic line ending processing.
X.PP
XThe qx// construct is now a synonym for backticks.
X.PP
X$0 may now be assigned to set the argument displayed by
X.I ps (1).
X.PP
XThe new @###.## format was omitted accidentally from the description
Xon formats.
X.PP
XIt wasn't known at press time that s///ee caused multiple evaluations of
Xthe replacement expression.  This is to be construed as a feature.
X.PP
X(LIST) x $count now does array replication.
X.PP
XThere is now no limit on the number of parentheses in a regular expression.
X.PP
XIn double-quote context, more escapes are supported: \ee, \ea, \ex1b, \ec[,
X\el, \eL, \eu, \eU, \eE.  The latter five control up/lower case translation.
X.PP
XThe
X.B $/
Xvariable may now be set to a multi-character delimiter.
X.SH BUGS
X.PP
X.I Perl
Xis at the mercy of your machine's definitions of various operations
Xsuch as type casting, atof() and sprintf().
X.PP
XIf your stdio requires an seek or eof between reads and writes on a particular
Xstream, so does
X.IR perl .
X(This doesn't apply to sysread() and syswrite().)
X.PP
XWhile none of the built-in data types have any arbitrary size limits (apart
Xfrom memory size), there are still a few arbitrary limits:
Xa given identifier may not be longer than 255 characters;
Xsprintf is limited on many machines to 128 characters per field (unless the format
Xspecifier is exactly %s);
Xand no component of your PATH may be longer than 255 if you use \-S.
X.PP
X.I Perl
Xactually stands for Pathologically Eclectic Rubbish Lister, but don't tell
Xanyone I said that.
X.rn }` ''
!STUFFY!FUNK!
echo Extracting eg/nih
sed >eg/nih <<'!STUFFY!FUNK!' -e 's/X//'
Xeval "exec /usr/bin/perl -Spi.bak $0 $*"
X	if $running_under_some_shell;
X
X# $Header: nih,v 4.0 91/03/20 01:11:29 lwall Locked $
X
X# This script makes #! scripts directly executable on machines that don't
X# support #!.  It edits in place any scripts mentioned on the command line.
X
Xs|^#!(.*)|#!$1\neval "exec $1 -S \$0 \$*"\n\tif \$running_under_some_shell;|
X	if $. == 1;
!STUFFY!FUNK!
echo " "
echo "End of kit 10 (of 36)"
cat /dev/null >kit10isdone
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 25 26 27 28 29 30 31 32 33 34 35 36; 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."
	for combo in *:AA; do
	    if test -f "$combo"; then
		realfile=`basename $combo :AA`
		cat $realfile:[A-Z][A-Z] >$realfile
		rm -rf $realfile:[A-Z][A-Z]
	    fi
	done
	rm -rf kit*isdone
	chmod 755 Configure
	;;
    *)  echo "You have run$run."
	echo "You still need to run$todo."
	;;
esac
: Someone might mail this, so...
exit

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.