Working with the File System

Perl has a number of built-in functions that can manipulate the filesystem

File Input and Output Functions

Opening Pipes

Two commands can be linked using a pipe. The first commands standard output is piped (linked) to the second connads standard input. To do this we need to associate the file with the command by calling open.

Opening pipe example
(output)

open (MESAAGE, "| mail paul.valle@datadisk.co.uk");
print MESSAGE ("Hello how is the website coming along?");
close (MESSAGE);

Note: The call to open establishes a pipe to the command "mail paul.valle@datadisk.co.uk", the file variable MESSAGE is now associated with this pipe. The call to print add the line to the message to be sent. The call to close closes the pipe and the mail program can then send the mail message.

Opening pipe example
(input)
open (CAT, "cat file*|");
$input = <CAT>;                   ## variable input will now have the cat'ed contents of all the files

Redirecting One File to Another

Unix allows you to direct both the standard outfile file and the standard error file to the same output file. You can also perform the same task with Perl

Redirecting example

open (STDOUT, ">file1") || die("ERROR: open STDOUT failed");
open (STDERR, ">&SDOUT") || die ("ERROR: open STDERR failed");

$| = 1;                           ## turn buffering off for STDOUT
select (STDERR);                  ## change the default file to STDERR (normal default file is STDOUT)
$| = 1;                           ## turn buffer off for STDERR

print STDOUT ("Line One\n");
print STDERR ("Line Two\n");

close(STDOUT);
close(STDERR);

Select Function

This allows you to select a new default file, so that calls to print, write and printf write to file variable STDERR, unless a file variable is explicity specified

Select example

select (STDERR);                  ## This becomes the new default file

eof Function

The eof function checks whether the last input file read has been exhausted, eof returns a non-zero value when all the file has been read.

eof example

while ($line = <>) {
   print ($line);
   if (eof) {                       ## the eof returns a non-zero value, thus executing the if statement
      print ("------ END OF FILE CONTENTS -------\n");
   }
}

Note: you can use the eof() function as well, so you could do eof(MYFILE)

Seek and Tell

Perl provides two functions which enable you to skip forward or backward in a file so that you can skip or re-read data.

seek example

seek(MYFILE, 0, 0);           ## skip to beginning of file
seek(MYFILE, 0, 2);           ## skip to the end of the file

seek(MYFILE, 80, 1);          ## skip forward 80 bytes
seek(MYFILE, -80, 1);         ## skip backward 80 bytes

tell example $offset = tell(MYFILE);

System Read and Write Functions

Perl provides two other functions that read an input file and one function that can write to a file, use these functions if you want fast read and write speeds.

read example read (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
read (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar
sysread example sysread (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
sysread (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar
syswrite example syswrite (MYFILE, $scalar, 80);        ## read 80 bytes and store in variable $scalar

## Appending to an existing scalar variable
sysread (MYFILE, $scalar, 40, 80);    ## read 40 bytes, skip 80 bytes in $scalar then append to $scalar

Reading Characters using getc

Thyis function reads a single character of input from a file, this can be useful for "hot key" applications. These applications process one character at a time, instead one line at a time.

getc example while(1) {
   $char = getc(STDIN);
   last if ($char eq "\\");           ## remember the first \ is escaping the second \
   print ($char);
}

Directory-Manipulation Functions

mkdir create a new directory
chdir set a directory to be the current working directory
opendir In order to list a directory you need to open it first
closedir When you are fisnihed with a directory you close it
readdir when a directory is opened you can now read all the filenames or subdirectories within the directory.
telldir and seekdir You can skip forwards or backwards within a directory structure.
rewinddir You can rewind backwards in a directory
rmdir You can remove a directory, the directory must be empty first.
Examples
mkdir mkdir ("/u01/oracle/data01", 0777);
chdir chdir ("/u01/oracle/data01");
opendir opendir (DIR, "/u01/oracle/data01");
closedir closedir (DIR);
readdir $filename = readdir(DIR);             ## read the first filename of the directory
@files = readdir(DIR);                ## read all the filenames into an array
telldir and seekdir $location_path = tell(DIR);           ## tells where abouts you are in the directory structure

seekdir(DIR, "/u01/oracle/data01");   ## set DIR to the new location
rewinddir rewinddir(DIR);
rmdir rmdir(DIR);                           ## directory must be empty

File-Attribute Functions

You can also use a number of the file test-operators with some of the commands below, to see a full listing check the perl cheat sheet.

rename change the name of a file
unlink and link use unlink to delete a file and use link to create hard links
symlink used to create symbolic links (soft link)
readlink returns the filename to which the file is linked to.
chmod changes access permissions
chown changes the owner of a file
umask sets the default access permissions for a file
truncate reduce a files size to a specified length
stat retrieves information about a particular file
lstat same as stat but presumes that the filename passed is a symbolic link
time to obtain the number of elapsed seconds from Jan 1 1970 to the npresent time, call this function
gmtime and localtime convert the value returned by time to either Greenwich Mean Time or your computers local time
utime set access and modification times of files
fileno return the Inode number of the file
flock and fcntl flock is a file locking function and fcntl provides constants for use with various Perl built-in functions
Examples
rename rename("file1", "file2");                      ## rename file1 to file2
unlink and link

files_deleted = unlink ("file1", "file2");     ## delete the files file1 and file2, returns number of
                                               ## files acutally deleted

link("/u/pvalle/file1", "/u/pvalle/file2");    ## create a hard link

symlink symlink("/u/pvalle/file1", "/u/pvalle/file2"); 
readlink $linkname = readlink("/u/pvalle/file2");       ## $linkname will contain the actaully filename
chmod ## chmod (<perms>, <files>);
chmod (0777, "file1");
chmod (0777, @filelist);
chown # chown (<userid>,<groupid>, <files>);
chown (17, -1, "file1");
chown (17, -1, @filelist);
umask $oldmask = umask(0022);                        ## $oldmask will contain the old mask value
$current_mask = umask();                       ## get the current mask value
truncate truncate ("/u/pvalle/logfile.log", 5000);      ## truncate file to 5000 bytes
stat stat("/u/pvalle/logfile.log");

Note: stat returns a list detailing information on the file
lstat lstat("/u/pvalle/logfile.log");
time $currtime = time();                            ## returned elapsed-seconds value
gmtime and localtime

$timelist = gmtime(time());
print $timelist;

$timelist = localtime(time());
print $timelist;

utime $acctime = -A "file1";
$modtime = -M "file1";
utime( $acctime, $modtime, "file2");           ## set the access & modification times the same as file1
fileno $filedesc = fileno(MYFILE);
flock and fcntl fcntl (<filevar>,<fcntlrtn>,<value>);
flock (<filevar>,<flockop>);

Note: best to see the Unix man pages for fcntl and flock