FTP upload directory and subdirectories in Perl - perl

I am trying to FTP a directory that has subdirectories with files and images using Perl.
I tried using $ftp->rput() under Net::FTP::Recursive. But this uploads all files under local current working directory.
Is there a way to give the path of local directory and all folders and files are uploaded. Please guide.

You need to change your own working directory temporarily.
rput ( [FlattenTree => 1] [,RemoveLocalFiles => 1] )
The recursive put
method call. This will recursively send the local current working
directory and its contents to the ftp object's current working
directory.
Perl's builtin chdir can be used to change the directory. Use the Cwd module to get the current one if you need to go back.
use strict;
use warnings;
use Cwd;
use Net::FTP::Recursive;
# ...
# get the current directory
my $old_current_dir = getcwd();
# change directory to the one you want to upload
chdir('path/to/updloaddir');
# upload
$ftp->rput();
# change back
chdir($old_current_dir);

Related

recursively file delete from directory in perl

I am new in perl script. I want to write perl which delete previous backup file and extract new backup file from dropbox and rename with specific file name.
Example:
backup location:
D:\Database\store_name\ containing .bak files
Actual folder data
D:\Database\Mahavir Dhanya Bhandar\ contain .bak file
D:\Database\Patel General Store\ containg .bak files
..so on
How can write perl script code which delete *.bak files store_recursively
2.extract new backup file from dropbox and rename with specific file name.
Have you looked into walking your file tree. http://rosettacode.org/wiki/Walk_a_directory/Recursively. Combine this with simple file operations (copying, deleting, etc.) and you should be good.
use File::Find qw(find);
my $dir = "D:\Database\Store_Name";
find sub {unlink $File::Find::name if /\.bak$/}, $dir;
and assuming that connectToDropbox() connects to your dropbox
use File::Copy;
use File::Find qw(find);
my $backup = connectToDropbox();
my $dir = "D\Database\Store_Name";
find sub {copy($backup -> getFile("file"), "newFile")} $dir;
of course, this assumes that you already can set up a connection and such to Dropbox. If not, there is a good CPAN libraryhere you can check out.

perl CGI to write file to sibling directory

current folder structure is as follows
/main/site/script.cgi
I want to be able to write to a file at
main/logs/mylog.log
How can I do this without giving the absolute path ? since This can be deployed to different servers, I wont want to have to change this every time its deployed.
To access a directory using a relative path, you need to establish first what that path will be relative to. That means you need to find out what the current working directory is for running CGI scripts.
If you add this program to your server and call it up on a browser you will see the current working directory that that server applies to all of its CGI programs.
use strict;
use warnings;
use CGI ':standard';
use Cwd 'getcwd';
print header('text/plain');
printf "Current working directory: %s\n", getcwd;
If, for instance, you find that the current working directory is /main/site then you can create the file using the path ../logs/mylog.log.

Perl Rar a whole folder

I want to rar a whole folder with Perl and Archive::Rar. For example the folder /root/pictures.
I have found only a way to rar single files.
I tried to find all files in the folder and rar them, but then I always have the whole path sticking to them (/root/pictures) in the rar archive.
I want only the /pictures folder plus its contents. Is that possible?
The folder structure of the files stored in the archive will be the same as the file names that you pass to the Add method. (Although you can add them without any containing folder at all using the -excludepaths option.)
If you chdir to the \root directory before adding the files to the archive, and specify all your files as pictures\file1.jpg etc. then the result should be as you want.
Something like this
use strict;
use warnings;
use Archive::Rar;
use autodie;
chdir '\root';
my $rar = Archive::Rar->new(-archive => 'pictures.rar');
$rar->Add(-files => [ glob 'pictures\*' ]);
Clearly you could add a path to the rar file name if you want the archive stored elsewhere.
At first you have to get a list of files from defined directory:
use File::Find;
my #content;
find( \&wanted, '/some/path');
sub wanted {
push #content, $File::Find::name;
return;
}
After that you may use the Archive::Rar to pack it.
use Archive::Rar;
my $rar = Archive::Rar->new();
$rar->Add(
-size => $size_of_parts,
-archive => $archive_filename,
-files => \#content,
);

relative file paths in perl

I have a perl script which is using relative file paths.
The relative paths seem to be relative to the location that the script is executed from rather than the location of the perl script. How do I make my relative paths relative to the location of the script?
For instance I have a directory structure
dataFileToRead.txt
->bin
myPerlScript.pl
->output
inside the perl script I open dataFileToRead.txt using the code
my $rawDataName = "../dataFileToRead.txt";
open INPUT, "<", $rawDataName;
If I run the perl script from the bin directory then it works fine
If I run it from the parent directory then it can't open the data file.
FindBin is the classic solution to your problem. If you write
use FindBin;
then the scalar $FindBin::Bin is the absolute path to the location of your Perl script. You can chdir there before you open the data file, or just use it in the path to the file you want to open
my $rawDataName = "$FindBin::Bin/../dataFileToRead.txt";
open my $in, "<", $rawDataName;
(By the way, it is always better to use lexical file handles on anything but a very old perl.)
To turn a relative path into an absolute one you can use Cwd :
use Cwd qw(realpath);
print "'$0' is '", realpath($0), "'\n";
Start by finding out where the script is.
Then get the directory it is in. You can use Path::Class::File's dir() method for this.
Finally you can use chdir to change the current working directory to the directory you just identified.
So, in theory:
chdir(Path::Class::File->new(abs_path($0))->dir());
Relative paths are relative to the current working directory. If you don't have any control over the working directory then you need to find a more robust way to spcecify your file paths, e.g. use absolute paths, or perhaps relative paths which are relative to some specific location within the file system.

Redirect unzip output to particular directory using Perl

I want to uncompress zipped file say, files.zip, to a directory that is different from my working directory.
Say, my working directory is /home/user/address and I want to unzip files in /home/user/name.
I am trying to do it as follows
#!/usr/bin/perl
use strict;
use warnings;
my $files= "/home/user/name/files.zip"; #location of zip file
my $wd = "/home/user/address" #working directory
my $newdir= "/home/user/name"; #directory where files need to be extracted
my $dir = `cd $newdir`;
my #result = `unzip $files`;
But when run the above from my working directory, all the files get unzipped in working directory. How do I redirect the uncompressed files to $newdir?
unzip $files -d $newdir
Use Perl command
chdir $newdir;
and not the backticks
`cd $newdir`
which will just start a new shell, change the directory in that shell, and then exit.
Though for this example, the -d option to unzip is probably the simplest way to do what you want (as mentioned by ennuikiller), for other types of directory-changing, I like the File::chdir module, which allows you to localize directory changes, when combined with the perl "local" operator:
#!/usr/bin/perl
use strict;
use warnings;
use File::chdir;
my $files= "/home/user/name/files.zip"; #location of zip file
my $wd = "/home/user/address" #working directory
my $newdir= "/home/user/name"; #directory where files need to be extracted
# doesn't work, since cd is inside a subshell: my $dir = `cd $newdir`;
{
local $CWD = $newdir;
# Within this block, the current working directory is $newdir
my #result = `unzip $files`;
}
# here the current working directory is back to what it was before
You can also use the Archive::Zip module. Look specifically at the extractToFileNamed:
"extractToFileNamed( $fileName )
Extract me to a file with the given name. The file will be created with default modes. Directories will be created as needed. The $fileName argument should be a valid file name on your file system. Returns AZ_OK on success. "