Perl Input/Output Functions
binmode(FILEHANDLE)
binmode FILEHANDLE
Arranges for the file to be read in binary mode in operating systems that distinguish between binary and text files. Files that are not read in binary mode have CR LF sequences translated to LF on input and LF translated to CR LF on output. binmode has no effect under Unix. If FILEHANDLE is an expression, the value is taken as the name of the filehandle.
close(FILEHANDLE)
close FILEHANDLE
Closes the file or pipe associated with the file handle. You don't have to close FILEHANDLE if you are immediately going to do another open on it, since open will close it for you. (See open.) However, an explicit close on an input file resets the line counter (`$.'), while the implicit close done by open does not. Also, closing a pipe will wait for the process executing on the pipe to complete, in case you want to look at the output of the pipe afterwards. Closing a pipe explicitly also puts the status value of the command into `$?'. Example:
open(OUTPUT, '|sort >foo'); # pipe to sort
... # print stuff to output
close OUTPUT; # wait for sort to finish
open(INPUT, 'foo'); # get sort's results
FILEHANDLE may be an expression whose value gives the real filehandle name.
eof(FILEHANDLE)
eof()
eof
Returns 1 if the next read on FILEHANDLE will return end of file, or if FILEHANDLE is not open. FILEHANDLE may be an expression whose value gives the real filehandle name. (Note that this function actually reads a character and the ungetc's it, so it is not very useful in an interactive context.) An eof without an argument returns the eof status for the last file read. Empty parentheses `()' may be used to indicate the pseudo file formed of the files listed on the command line, i.e. `eof()' is reasonable to use inside a `while (<>)' loop to detect the end of only the last file. Use `eof(ARGV)' or eof without the parentheses to test EACH file in a `while (<>)' loop. Examples:
# insert dashes just before last line of last file
while (<>) {
if (eof()) {
print "--------------\n";
}
print;
}
# reset line numbering on each input file
while (<>) {
print "$.\t$_";
if (eof) { # Not eof().
close(ARGV);
}
}
getc(FILEHANDLE)
getc FILEHANDLE
getc
Returns the next character from the input file attached to FILEHANDLE, or a null string at EOF. If FILEHANDLE is omitted, reads from STDIN.
open(FILEHANDLE,EXPR)
open(FILEHANDLE)
open FILEHANDLE
Opens the file whose filename is given by EXPR, and associates it with FILEHANDLE. If FILEHANDLE is an expression, its value is used as the name of the real filehandle wanted. If EXPR is omitted, the scalar variable of the same name as the FILEHANDLE contains the filename. If the filename begins with `<' or nothing, the file is opened for input. If the filename begins with `>', the file is opened for output. If the filename begins with `>>', the file is opened for appending. (You can put a `+' in front of the `>' or `<' to indicate that you want both read and write access to the file.) If the filename begins with `|', the filename is interpreted as a command to which output is to be piped, and if the filename ends with a `|', the filename is interpreted as command which pipes input to us. (You may not have a command that pipes both in and out.) Opening `-' opens `STDIN' and opening `>-' opens `STDOUT'. open returns non-zero upon success, the undefined value otherwise. If the open involved a pipe, the return value happens to be the pid of the subprocess. Examples:
$article = 100;
open article || die "Can't find article $article: $!\n";
while (
) {...
open(LOG, '>>/usr/spool/news/twitlog');
# (log is reserved)
open(article, "caesar <$article |");
# decrypt article
open(extract, "|sort >/tmp/Tmp$$");
# $$ is our process#
# process argument list of files along with any includes
foreach $file (@ARGV) {
do process($file, 'fh00'); # no pun intended
}
sub process {
local($filename, $input) = @_;
$input++; # this is a string increment
unless (open($input, $filename)) {
print STDERR "Can't open $filename: $!\n";
return;
}
while (<$input>) { # note the use of indirection
if (/^#include "(.*)"/) {
do process($1, $input);
next;
}
... # whatever
}
}
You may also, in the Bourne shell tradition, specify an EXPR beginning with `>&', in which case the rest of the string is interpreted as the name of a filehandle (or file descriptor, if numeric) which is to be duped and opened. You may use `&' after `>', `>>', `<', `+>', `+>>' and `+<'. The mode you specify should match the mode of the original filehandle. Here is a script that saves, redirects, and restores `STDOUT' and `STDERR':
#!/usr/bin/perl
open(SAVEOUT, ">&STDOUT");
open(SAVEERR, ">&STDERR");
open(STDOUT, ">foo.out") || die "Can't redirect stdout";
open(STDERR, ">&STDOUT") || die "Can't dup stdout";
select(STDERR); $| = 1; # make unbuffered
select(STDOUT); $| = 1; # make unbuffered
print STDOUT "stdout 1\n"; # this works for
print STDERR "stderr 1\n"; # subprocesses too
close(STDOUT);
close(STDERR);
open(STDOUT, ">&SAVEOUT");
open(STDERR, ">&SAVEERR");
print STDOUT "stdout 2\n";
print STDERR "stderr 2\n";
If you open a pipe on the command `-', i.e. either `|-' or `-|', then there is an implicit fork done, and the return value of open is the pid of the child within the parent process, and 0 within the child process. (Use `defined($pid)' to determine if the open was successful.) The filehandle behaves normally for the parent, but i/o to that filehandle is piped from/to the `STDOUT'/`STDIN' of the child process. In the child process the filehandle isn't opened--i/o happens from/to the new `STDOUT' or `STDIN'. Typically this is used like the normal piped open when you want to exercise more control over just how the pipe command gets executed, such as when you are running setuid, and don't want to have to scan shell commands for metacharacters. The following pairs are equivalent:
open(FOO, "|tr '[a-z]' '[A-Z]'");
open(FOO, "|-") || exec 'tr', '[a-z]', '[A-Z]';
open(FOO, "cat -n '$file'|");
open(FOO, "-|") || exec 'cat', '-n', $file;
Explicitly closing any piped filehandle causes the parent process to wait for the child to finish, and returns the status value in `$?'. Note: on any operation which may do a fork, unflushed buffers remain unflushed in both processes, which means you may need to set `$|' to avoid duplicate output. The filename that is passed to open will have leading and trailing whitespace deleted. In order to open a file with arbitrary weird characters in it, it's necessary to protect any leading and trailing whitespace thusly:
$file =~ s#^(\s)#./$1#;
open(FOO, "< $file\0");
pipe(READHANDLE,WRITEHANDLE)
Opens a pair of connected pipes like the corresponding system call. Note that if you set up a loop of piped processes, deadlock can occur unless you are very careful. In addition, note that perl's pipes use stdio buffering, so you may need to set `$|' to flush your WRITEHANDLE after each command, depending on the application.
[Requires version 3.0 patchlevel 9.]
print(FILEHANDLE LIST)
print(LIST)
print FILEHANDLE LIST
print LIST
print
Prints a string or a comma-separated list of strings. Returns non-zero if successful. FILEHANDLE may be a scalar variable name, in which case the variable contains the name of the filehandle, thus introducing one level of indirection. (NOTE: If FILEHANDLE is a variable and the next token is a term, it may be misinterpreted as an operator unless you interpose a `+' or put parens around the arguments.) If FILEHANDLE is omitted, prints by default to standard output (or to the last selected output channel--see select()).If LIST is also omitted, prints `$_' to `STDOUT'. To set the default output channel to something other than `STDOUT' use the select operation. Note that, because print takes a LIST, anything in the LIST is evaluated in an array context, and any subroutine that you call will have one or more of its expressions evaluated in an array context. Also be careful not to follow the print keyword with a left parenthesis unless you want the corresponding right parenthesis to terminate the arguments to the print---interpose a `+' or put parens around all the arguments.
printf(FILEHANDLE LIST)
printf(LIST)
printf FILEHANDLE LIST
printf LIST
printf
Equivalent to a `print FILEHANDLE sprintf(LIST)'.
read(FILEHANDLE,SCALAR,LENGTH,OFFSET)
read(FILEHANDLE,SCALAR,LENGTH)
Attempts to read LENGTH bytes of data into variable SCALAR from the specified FILEHANDLE. Returns the number of bytes actually read, or undef if there was an error. SCALAR will be grown or shrunk to the length actually read. An OFFSET may be specified to place the read data at some other place than the beginning of the string. This call is actually implemented in terms of stdio's fread call. To get a true read system call, see sysread.
select(RBITS,WBITS,EBITS,TIMEOUT)
This calls the select system call with the bitmasks specified, which can be constructed using fileno() and vec(), along these lines:
$rin = $win = $ein = '';
vec($rin,fileno(STDIN),1) = 1;
vec($win,fileno(STDOUT),1) = 1;
$ein = $rin | $win;
If you want to select on many filehandles you might wish to write a subroutine:
sub fhbits {
local(@fhlist) = split(' ',$_[0]);
local($bits);
for (@fhlist) {
vec($bits,fileno($_),1) = 1;
}
$bits;
}
$rin = &fhbits('STDIN TTY SOCK');
The usual idiom is:
($nfound,$timeleft) =
select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
or to block until something becomes ready:
$nfound = select($rout=$rin, $wout=$win,
$eout=$ein, undef);
Any of the bitmasks can also be undef. The timeout, if specified, is in seconds, which may be fractional. NOTE: not all implementations are capable of returning the `$timeleft'. If not, they always return `$timeleft' equal to the supplied `$timeout'.
seek(FILEHANDLE,POSITION,WHENCE)
Randomly positions the file pointer for FILEHANDLE, just like the fseek() call of stdio. FILEHANDLE may be an expression whose value gives the name of the filehandle. Returns 1 upon success, 0 otherwise.
select(FILEHANDLE)
select
Returns the currently selected filehandle. Sets the current default filehandle for output, if FILEHANDLE is supplied. This has two effects: first, a write or a print without a filehandle will default to this FILEHANDLE. Second, references to variables related to output will refer to this output channel. For example, if you have to set the top of form format for more than one output channel, you might do the following:
select(REPORT1);
$^ = 'report1_top';
select(REPORT2);
$^ = 'report2_top';
FILEHANDLE may be an expression whose value gives the name of the actual filehandle. Thus:
$oldfh = select(STDERR); $| = 1; select($oldfh);
tell(FILEHANDLE)
tell FILEHANDLE
tell
Returns the current file position for FILEHANDLE. FILEHANDLE may be an expression whose value gives the name of the actual filehandle. If FILEHANDLE is omitted, assumes the file last read.
write(FILEHANDLE)
write(EXPR)
write
Writes a formatted record (possibly multi-line) to the specified file, using the format associated with that file. By default the format for a file is the one having the same name is the filehandle, but the format for the current output channel (see select) may be set explicitly by assigning the name of the format to the `$~' variable. Top of form processing is handled automatically: if there is insufficient room on the current page for the formatted record, the page is advanced by writing a form feed, a special top-of-page format is used to format the new page header, and then the record is written. By default the top-of-page format is the name of the filehandle with _TOP appended, but it may be dynamically set to the format of your choice by assigning the name to the `$^' variable while the filehandle is selected. The number of lines remaining on the current page is in variable `$-', which can be set to 0 to force a new page. If FILEHANDLE is unspecified, output goes to the current default output channel, which starts out as `STDOUT' but may be changed by the select operator. If the FILEHANDLE is an EXPR, then the expression is evaluated and the resulting string is used to look up the name of the FILEHANDLE at run time. See section Formats, for more info. Note that write is NOT the opposite of read.