File-Remote
view release on metacpan or search on metacpan
my($self, $file, $suffix) = _self_or_default(@_);
croak "Bad usage of backup" unless ($file);
$suffix ||= 'bkup';
my($rhost, $lfile) = _parsepath($file);
my($bhost, $bfile) = _parsepath($suffix);
# See if the thing is a suffix or filename
$bfile = "$file.$suffix" unless ($bfile =~ m@/@); # a path name
# All we do now if drop thru to our own copy routine
_debug("backup() calling copy($file, $bfile)");
$self->copy($file, $bfile) or return undef;
return 1;
}
#######
# Usage: $remote->append($file, @file);
#
# This is just like writefile, only that it appends to the file
# rather than overwriting it.
#######
*rappend = \&append;
sub append {
my($self, $file, @file) = _self_or_default(@_);
croak "Bad usage of append" unless ($file);
my @prefile = $self->readfile($file) or return undef;
my @newfile = (@prefile, @file) or return undef;
$self->writefile($file, @newfile) or return undef;
return 1;
}
#######
# Usage: $remote->prepend($file, @file);
#
# This is just like writefile, only that it prepends to the file
# rather than overwriting it.
#######
*rprepend = \&prepend;
sub prepend {
my($self, $file, @file) = _self_or_default(@_);
croak "Bad usage of prepend" unless ($file);
my @postfile = $self->readfile($file) or return undef;
my @newfile = (@file, @postfile) or return undef;
$self->writefile($file, @newfile) or return undef;
return 1;
}
1;
#------------------------------------------------
# Documentation starts down here...
#------------------------------------------------
__END__ DATA
=head1 NAME
File::Remote - Read/write/edit remote files transparently
=head1 SYNOPSIS
#
# Two ways to use File::Remote
#
# First, the function-based style. Here, we can use the
# special :replace tag to overload Perl builtins!
#
use File::Remote qw(:replace); # special :replace tag
# read from a remote file
open(REMOTE, "host:/remote/file") or die $!;
print while (<REMOTE>);
close(REMOTE);
# writing a local file still works!
open(LOCAL, ">>/local/file");
print LOCAL "This is a new line.\n";
close(LOCAL);
mkdir("host:/remote/dir", 0755);
unlink("host:/remote/file");
unlink("/local/file"); # still works too!
symlink("host:/remote/src", "host:/remote/dest");
chown("root", "other", "host:/remote/dir/file");
chmod(0600, "host:/remote/dir/file");
#
# Next, the object-oriented style, if you don't want to
# mess with the builtins.
#
use File::Remote;
my $remote = new File::Remote;
# Standard filehandles
$remote->open(FILE, ">>host:/remote/file") or die $!;
print FILE "Here's a line that's added.\n";
$remote->close(FILE);
# Create a new file and change its permissions
$remote->mkdir("host:/remote/dir");
$remote->touch("host:/remote/dir/file");
# Move files around
$remote->copy("/local/file", "host:/remote/file") or warn $!;
$remote->move("host:/remote/file", "/local/file");
# Read and write whole files
my @file = $remote->readfile("host:/remote/file");
$remote->writefile("/local/file", @file);
# Backup a file with a suffix
$remote->backup("host:/remote/oldfile", "save");
# Use secure connection methods
my $secure = new File::Remote (rsh => "/usr/local/bin/ssh",
rcp => "/usr/local/bin/scp");
$secure->unlink("/local/file");
$secure->rmdir("host:/remote/dir");
=head1 DESCRIPTION
This module takes care of dealing with files regardless of whether
they're local or remote. It allows you to create and edit files without
having to worry about their physical location on the network. If a file
passed into a function is of the form C<host:/path/to/file>, then
C<File::Remote> uses rsh/rcp (or ssh/scp, depending on how you configure it)
to edit the file remotely. Otherwise, it assumes the file is local and
passes calls directly through to Perl's core functions.
The nice thing about this module is that you can use it for I<all> your
file calls, since it handles both remote and local files transparently.
This means you don't have to put a whole bunch of checks for remote files
in your code. Plus, if you use the function-oriented interface along with
the C<:replace> tag, you can actually redefine the Perl builtin file
functions. This means that your existing Perl scripts can automatically
handle remote files with no re-engineering(!).
There are two ways to program with C<File::Remote>, an object-oriented
style and a function-oriented style. Both methods work equally well,
it's just a matter of taste. One advantage of the object-oriented
method is that this allows you to read and write from different servers
using different methods (eg, rsh vs. ssh) simultaneously:
# Object-oriented method
use File::Remote;
my $remote = new File::Remote;
my $secure = new File::Remote (rsh => "/bin/ssh", rcp => "/bin/scp");
# Securely copy, write, and remove a file in one swoop...
$remote->open(LOCAL, "/local/file") or die "Open failed: $!\n";
$secure->open(REMOTE, "host:/remote/file") or die "Open failed: $!\n";
print REMOTE "$_" while (<LOCAL>);
$remote->close(LOCAL);
$secure->close(REMOTE);
# And let's move some files around securely
$secure->move("/local/file", "host:/remote/file");
$secure->copy("host:/remote/file", "/local/file");
To use the function-oriented interface, you must import the special tag
called C<:replace> which will actually replace the Perl builtin functions:
# Replace Perl's file methods with File::Remote's
use File::Remote qw(:replace);
open(FILE, ">host:/remote/file") or die "Open failed: $!\n";
print FILE "Hello, world!\n";
close(FILE) or die "Close failed: $!\n";
mkdir("/local/new/dir", "2775");
mkdir("host:/remote/new/dir");
chown("root", "other", "/local/new/dir");
unlink("host:/remote/file");
This is pretty neat; since C<File::Remote> will pass calls to local files
straight through to Perl's core functions, you'll be able to do all this
"transparently" and not care about the locations of the files. Plus,
this has the big advantage of making your existing Perl scripts capable
of dealing with remote files without having to rewrite any code.
Because the names for the C<File::Remote> methods clash with the Perl builtins,
if you use the function-oriented style with the C<:standard> tag there is
an extra 'r' added to the front of the function names. Thus, C<<$remote->open>>
becomes 'ropen' in the C<:standard> function-oriented version:
# Function-oriented method
use File::Remote qw(:standard); # use standard function names
setrsh("/share/bin/ssh");
setrcp("/share/bin/scp");
# same functionality, but there's an "r" prefix
ropen(FILE, "host:/remote/file") or die "Open failed: $!\n";
print while (<FILE>);
rclose(FILE) or die "Close failed: $!\n";
runlink("host:/remote/file");
rmkdir("host:/remote/dir");
rchmod("0700", "host:/remote/dir");
That's kinda nasty, though. I recommend you use the C<:replace> tag,
personally.
=head1 FUNCTIONS
Below are each of the functions you can make use of with C<File::Remote>.
Remember, for the function-oriented style, unless you use the C<:replace>
tag you'll have to add an extra 'r' to the start of each function name.
For all functions, the file arg can be either local or remote.
=head2 new(opt => val, opt => val)
This is the main constructor when you're using the object-oriented
method of calling. You only need to use this if you're using the
object-oriented calling form. You can pass it three arguments which
change how it works:
rsh - path to your rsh or ssh program
rcp - path to your rcp or scp program
tmp - path to your tmp directory
So, for example:
use File::Remote;
my $secure = File::Remote->new(rsh => '/usr/local/bin/ssh',
rcp => '/usr/local/bin/scp',
tmp => '/var/run');
$secure->copy($src, $dest);
The above would setup your C<$secure> object so that calls to methods on
it would use ssh and scp for connections.
=head2 setrsh(prog) ; setrcp(prog) ; settmp(dir)
These perform the equivalent functionality to setting the above flags,
for use in the function-oriented method of calling. So, if you were to
decide you didn't want to use the OO method, but instead wanted to use
the drop-in replacement function method (which I prefer):
( run in 0.745 second using v1.01-cache-2.11-cpan-39bf76dae61 )