Perl SSH to remote server and check file exists - perl

I have developed a script which should login into remote server and do certain operation.
In remote server it will check for sample_file.txt file exists or not, if YES then it should create create_user_file.txt file in home path with certain set of data.
The thing here is I am able to do ssh to remote machine though below script but unable to check for the files since I don't have idea how we can open the remote session and do all the operation.
Below is my code:
#!/usr/bin/perl
use Net::OpenSSH;
.
.
.
foreach my $ip( #list_of_ips){
print "Connecting to $ip...\n";
my $ssh = OpenSSH_Connection( $ip, $user, $passwd );
print "Connected!\n";
$dir = "/remote/server/home/path/";
$file = $dir."sample_file.txt";
if (-e $file){ #if sample_file.txt exists then create user file
open(my $fh, '>', $dir."create_user_file.txt") || die "Couldn't open file $!";;
print $fh "ID=123&PW=Passw0rd";
close $fh;
}
last if($ssh); #if connection is success no need to login into another server
$ssh->close();
}
sub OpenSSH_Connection {
my ( $host, $user, $passwd ) = #_;
my $ssh = Net::OpenSSH->new("$user:$passwd\#$host");
$ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;
return $ssh;
}
Here in the code, below part of code should be executed in the remote server. But its been checking for a file from where I am executing this script.
if (-e $file){ #if sample_file.txt exists then create user file
open(my $fh, '>', $dir."create_user_file.txt") || die "Couldn't open file $!";;
print $fh "ID=123&PW=Passw0rd";
close $fh;
}
How can I keep open the remote session of the server and execute above code, or do we have any Perl module which could do this kind of operation from local server. TIA.

Your assumption that Net::SSH will make remote resources available locally is incorrect.
SSH creates encrypted channel to remote system and drops you either into shell, or runs remote command (for example perl/shell script), or allows to copy/retrieve a file.
You can open SSH channel into remote shell and run commands as on local computer, but if you want to check if file exists on remote system then you have to communicate it through remote shell or perl script.
Probably what you are after is SSH FS which may make remote files available locally.
I must make note that users on local and remote system can have different id on system level and it might be not what you want (manipulate files of different user). This approach may work well if your local and remote id is the same and belongs to you.
I guess that most easy way would be write perl script on remote system and pass some arguments to it. The script on remote system will do rest part of the job.
In such situation you could use Net::SSH2 to establish connection into remote shell and then run remote perl script with parameters.
To get a better idea how it works without creating long post I refer you to PerlMonks Net::SSH2 demo.
Other more difficult way would be writing enough perl code to establish connection with remote system over SSH2 protocol to remote perl script with capability to 'translate' your local commands
$chan->command($argument)
into remote perl code blocks to perform particular task.
Net::SSH2

Related

How to read a file which is on server using perl script

I have a file on my perforce client which i can read from the client but i want to read it from the depot instead from my client and i Have to achieve this using a Perl script and my client name is ata and its root directory is /home/ata/hw
The following code is written for the file on my client
my $clients_file="/home/ata/hw/hard/ip/golden_design_map.cfg";
open(READ,"<$clients_file") or die "Couldn't open the file for reading:$!";
But this is what i want to achieve
my $clients_file="//hw/hard/ip/golden_design_map.cfg";
open(READ,"<$clients_file") or die "Couldn't open the file for reading:$!";
Here //hw/hard/ip/golden_design_map.cfg is the file on the depot or the server.
Is there any module which i can use.Any help is truly appreciated.Thanks in advance.
You can use the p4 command line like this:
open( READ, "p4 print -q $clients_file|" ) or die "Couldn't execute p4:$!";
This assumes that your environment is already set up to run p4 commands (p4 executable in the PATH, valid settings for P4PORT and P4USER, valid login ticket acquired by having run "p4 login" previously, etc).
Or you can use the Perforce Perl module: http://www.perforce.com/perforce/doc.current/manuals/p4script/02_perl.html
You could use File::Remote module.
Synopsis:
use File::Remote;
# read from a remote file
open(REMOTE, "host:/remote/file") or die $!;
print while (<REMOTE>);
close(REMOTE);

perl ssh then read file on remote server

I need to
connect to a remote server; then
do some things, like open and read the contents of a file.
For step 1:
my $server = "remoteservername.company.com";
my $ssh = Net::SSH::Perl->new("$server", debug => 1, protocol => 2, StrictHostKeyChecking => "no") or die "Error connecting server $server";
yields msg on terminal
Connection established.
so I presume I am ssh connected to remote server, via the code.
For step 2, how do i open and read a file on the remote server using code from the local server? this is the best i can do so far:
use strict;
use warnings;
use diagnostics;
use warnings::register;
use Net::SSH::Perl;
use Net::SSH::Expect;
use Math::BigInt lib => "Calc,GMP,Pari";
my $server = "server09";
my $ssh = Net::SSH::Perl->new("$server", debug => 1, protocol => 2, StrictHostKeyChecking => "no") or die "Error connecting server $server";
#open(FILE, "/home/myid/f09.txt") || print("Unable to open test.o\n"); #works, on local, opens file[does not fail].
#open(FILE, "server09://home/myid/f09.txt") || print("Unable to open test.o\n"); #---> error: "Unable to open test.o"
my #remote_text = `this text is put into array.`;
my $remote_text = join ('',#remote_text);
open (FILE,'>/home/myid/f09.txt');
print FILE "$remote_text";
close (FILE);
exit(0);
yet, it does not add anything to existing file f09.txt; also if i delete the file, the open does not create it. no errors, but this does not seem to contact the remote file.
just a simple explanation of ssh, then read from remote file would be helpful. other examples i see aren't cutting it. of course, could be me, long day, gotta walk away from it for a while. your time is very much appreciated!
You are essentially trying to modify a file that exists on another machine over SSH.
File operations functions cannot handle that.
Is it possible for you to download the file from the other server, update on your local and re-upload the file?
You may also want to experiment with the ssh command:
my #remote_text = ('this text is put into array.');
my $remote_text = join ('',#remote_text);
my #args = ("ssh server09", "echo '$remote_text' > /home/myid/f09.txt");
system(#args) == 0 or die "system #args failed: $?"
For performing interesting things over an SSH connection to another machine, you might like to try IPC::PerlSSH. From one of its examples:
use IPC::PerlSSH;
my $ips = IPC::PerlSSH->new( Host => "over.there" );
$ips->use_library( "FS", qw( mkdir chmod writefile ) );
$ips->call( "mkdir", "/tmp/testing" );
$ips->call( "chmod", 0600, "/tmp/testing" );
$ips->call( "writefile", "/tmp/testing/secret", <<EOF );
Some secret contents of my file here
EOF

How to create a Zip file on a remote server in perl

actualy im using Net::FTP::Recursive to download a directory structure , it works nice for what is required. But since some folders have more than 100/ files, downloading then can take ages. Since a zip file is faster do download, how i could, using perl connect to a remote server via ftp and create a zip file from the remote server/folder to download ?
use Net::Config;
use Net::FTP::Recursive;
$ftp = Net::FTP::Recursive->new("$hostname:$ftp_port", Debug => 0)
or die "Cannot connect to $hostname: $#";
$ftp->login($iLogin,$iPass)
or die "failed ", $ftp->message;
$ftp->binary()
or die "Cannot set to Binary";
$ftp->cwd("/admin/packages/$fileName")
or die "Cannot change working directory ", $ftp->message;
$ftp->rget( $fileName );
#or die "Download Failed ", $ftp->message;
$ftp->quit;
Thank you all for your time
The site(ARGS) method is designed for that. You can send a shell command and make it runs on remote server.
http://perldoc.perl.org/Net/FTP.html#METHODS
However, most of the FTP servers I know disabled that permission, so, good luck
I think you'd need to have SSH access to the system to run a ZIP command. But if that's the case, you could also use SCP to transfer your files more securely. FTP does everything in the open.
Thanks,
F.

How can I get STDERR and STDOUT of a command executed on a remote machine through SSH in Perl?

I have to connect to a remote machine via SSH executed through Expect module. I have to access the STDERR/STDOUT separately if possible and look at the output. I can redirect the output of the script e.g.
$command = "ssh <script> 2>/tmp/stderr.output"
$exp = Expect->spawn($command) or die "Cannot spawn\n";;
my #command1= $exp->expect(5);
but then I have to remotely connect again to check stderr.output.
Is there a way that expect returns the STDERR/STDOUT separately.
You might want to consider using Net::OpenSSH which provides a capture2 method:
($output, $errput) = $ssh->capture2(\%opts, #cmd)
captures the output sent to both stdout and stderr by #cmd on the remote machine.

Whilst using Perl::FTP, What shall I put in the host field for connecting to a Local computer connected on the network

I am using the Net::FTP in perl to do some file transfers. when I run the following code :-
Are there any issues with using the IP address ? Am I correct in providing this in the host field ?
use strict;
use Net::FTP;
my $host = "10.77.69.124";
my $user = "administrator";
my $password = "Password";
my $f = Net::FTP->new($host, Debug =>0) or die "Can't open $host\n";
$f->login($user, $password) or die "Can't log $user in\n";
The code is not able to connect to the remote host. Why is this happening ? Shouldn't this work with the IP address provided in the $host ?
The constructor of Net::FTP allows you to pass a single scalar value or an array of hosts to try. The value of this field should be the same as the PeerAddr from IO::Socket::INET (either a hostname or an ip address).
Have a closer look at what is happening by specifying Debug. If you are behind a firewall or a NAT setup, you should probably also set Passive to a non-zero value and make sure to check if the constructor failed by printing out $#.
my $ftp = Net::FTP->new(Host=>$host, Debug=>1, Passive=>1) || die $#;
If the constructor succeeded, you might want to check if any of the other methods fail:
$ftp->login($user, $pass) || die $ftp->message;
$ftp->cwd($path) || die $ftp->message;
By the way: If you are unsure if you've used the correct host parameter, you can ask Net::FTP which host it tried to connect to:
print $ftp->host, "\n";
If this still doesn't work, please provide a detailed output of your application.
Hope this helps.
First be sure that you can reach the remote side:
From command line use telnet (available on linux and windows too, a it different in syntax)
telnet host 21
If you are not able to connect the from commandline, check for firewall rules or maybe your FTP server running on different port?
If you are able to connect try out login with plain FTP commands:
USER user#remote.host
PASS yourpassword
This will use ACTIVE ftp connection to the remote. This is the old way.
Nowadays most ftp server use PASSIVE ftp. To test try this command out (from linux commandline)
ftp -v -p host
In perl you could use passive mode this way:
my $f = Net::FTP->new($host, Debug =>1, Passive => 1) or die "Can't open $host\n";
I hope this will help you.