I have a mojolicio server on a machine where I connect to it from another machine. I have a script that checks if the mojolicio is up - and run it if it is not running. I use the following command line to run the server:
ssh root#hostname 'cd /server_path/; (nohup /usr/bin/perl server_file >nohup.out &);'
The server_file is a script that raise the server is has the following script:
#!/usr/bin/env perl
use Mojo::Base -strict;
use File::Basename 'dirname';
use File::Spec::Functions qw(catdir splitdir);
# Source directory has precedence
my #base = (splitdir(dirname(__FILE__)), '..');
my $lib = join('/', #base, 'lib');
-e catdir(#base, 't') ? unshift(#INC, $lib) : push(#INC, $lib);
# Start commands for application
require Mojolicious::Commands;
Mojolicious::Commands->start_app('MyServer', 'daemon','-l','http://*:3030');
If the server is down and I run this command - I see in the machine that the server is up and running and it listening to the port it configured to listen to. Now, if I try to connect to the server from the browser it don't not load. It stuck on loading and in the end I got page not found. But if I run the same command from the server itself it works and I can load the homepage after it runs.
I found the problem..
If I use the nohup with the ssh then the server somehow won't be reachable - but when I run the server without the nohup as for example - using the following code:
ssh root#hostname 'cd /server_path/; (usr/bin/perl server_file );'
it works.
what may be the problem here?
Thanks a lot.
I found the solution :-) - the problem was with the nohup command - it was missing the:
2>nohup.out
I added it and it works now.
Thanks everybody.
Related
I need to put files in a remote directory using SFTP on a Windows machine. I've tried Net::SFTP::Foreign though I can't use it because it needs IO::Pty which is not available on Windows machine. What's the best/simplest way to do this?
Update With Requested Info:
Here are the versions I'm using:
Net::SFTP::Foreign : v 1.89
Net::SSH2 : v 0.69
Net::SFTP::Foreign::Backend::Net_SSH2 : v 0.09
and here is the gist of my code:
$ssh2 = Net::SSH2->new();
$ssh2->connect($host) || die "connect failed";
$ssh2->auth_password($user, $pass) || die "password auth failed";
$sftp = Net::SFTP::Foreign->new(ssh2 => $ssh2,
backend => 'Net_SSH2');
$sftp->error and
die "Unable to stablish SFTP connection: ". $sftp->error;
Right now I'm just trying to establish a connection. I will need to put files on the server. The erro I'm receiving is as follows:
Net::SSH2::timeout(ss, timeout) at C:/Strawberry/perl/site/lib/Net/SSH2.pm line 111, <STDIN> line 1.
The preferred way to use Net::SFTP::Foreign in Windows is probably to use the Net::SFTP::Foreign::Backend::Net_SSH2 backend (update: a Perl module available from CPAN) which uses Net::SSH2 under the hood (which is already included with Strawberry Perl, update: otherwise, you will need to build and install libssh2 yourself which sometimes is not as easy as it should be).
Another option is to tell Net::SFTP::Foreign to use the plink command to run the SSH connection (search for plink on the module docs). Update:plink is part of the PuTTY application distribution, a very popular SSH client that may be already installed in that machine.
Finally you can also try using Net::SSH::Any which provides its own backend for Net::SFTP::Foreign and can run on top of several SSH clients and modules... but it is still in beta!
I have several cross-platform scripts that are using Net::SFTP::Foreign using plink on windows and openssh on linux and it works great. Windows is using the latest strawberry perl release.
my $sftp = Net::SFTP::Foreign->new(
host=> $server,
ssh_cmd => $plink, #Contains full path to plink or path to ssh
user=> $user,
more => ['-i', $keyfile],
stderr_discard => 1,
);
The only thing about using the plink backend is that you have to first manually establish a connection using psftp or Putty gui so it stores the trust confirmation in the registry. After that it is good to go from the script.
The nice thing is you can just have the actual path to ssh or to plink defined in a system level config file and the script just reads what is needed on that particular platform. ie (...\bin\Putty\plink.exe or /usr/bin/ssh )
Not a pure Perl solution, but has been very robust. I don't see IO::Pty on any of my windows boxes so no dependency there for plink.
SFTP is actually SSH with a wrapper to simulate the FTP like commands, so a mdir is actually a ssh 'ls /path/to/dir'.
While there might be a Perl SFTP package that avoids IO::Pty, you might get to your solution much faster by just translating the "FTP" commands into their ssh / scp equivalents and looking at Net::SSH
--- Adding an Example as requested ---
#!/bin/env perl
use Net::OpenSSH ();
my $connection = Net::OpenSSH->new('somehost.com', user => 'myuser', password => 'mypassword' );
my #ls = $connection->capture("ls");
printf "remote listing is %s\n", join(', ', #ls);
This should list the files to your console.
You mentioned not having IO::Pty because it is not available for a windows machine. Perhaps you should be attempting to install IO::Pty::Easy. Note that Net::OpenSSH uses IO::Pty too, but that should be possible to do on windows, provided you also install Glib as indicated in this post http://www.perlmonks.org/bare/?node_id=856863
Good luck!
When I run below code through perl script at that time I always get error like connection refused so please any body can suggest to solve this issue.
ftp_check.pl:
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
my $host = '111.118.248.24';
#-- connect to ftp server
my $ftp = Net::FTP->new($host, Debug => 1) or die "Error connecting to $host: $!";
Message getting like "Error connecting to 111.118.248.24: Connection refused at ftp_check.pl line 10."
i supposed you server works properly, just for the case you can make some pings on it. Anyway, do you have a possibility to run in a terminal ( with ssh or some client like putty if you are a windows user ) following commands:
netstat -tulpena | grep -i LIST <<ENTER>>
Now you can see is there a FTP-Server which is running in a listener mode.
The second step would be to to use some ftp-client to check, that you can connect with your FTP-Server properly, just to see is there a firewall-rule in between, actually you could run "iptables -L" on a server to, but it will be easier just to use some ftp-client to make a verification of your ftp-server.
An other suggestion would be to use something more secure
and not the net::ftp-module. Perl has nice CPAN-Modules for SFTP (Net::FTP).
Cheers.
title: perl ssh to remote server, start service and capture pid
1-please tell me if i am not clear, or i if am otherwise frustrating as i ask questions - i do not want to bite the hand that feeds me!
2-original file is 180 lines long, but here is the gist:
#!/usr/bin/perl -w
use strict;
use warnings;
use Net::SSH::Perl;
use Net::SSH::Expect;
use Time::HiRes qw(usleep nanosleep);
Time::HiRes::sleep(5); #5 seconds #a look at "top" verifies this running .pl file pid.
my $remoteCmd = `ssh $remote_host -l $userID -i /home/$userID/.ssh/authorized_keys /sbin/service /etc/init.d/c3-mi-nodeserver start`;
my $servicePID = $$; #this should be pid for .pl file running.
print "servicePID: " . $servicePID . "\n"; #prints the pid of the running .pl file.
of course, you'll see variables that i populate to make it work.
one idea i have is: if i start a service, it will be the pid # of the currently running .pl file + 1; but, the new service started is on a remote server, so how can i capture it from the remote server and return it back to the local .pl file?
ideas?
With that ssh command there's no way to capture the PID of the process you just started on a remote host.
You would need to use another ssh to find the process id. But really - what are you trying to accomplish by doing so? Can you not use service status and service stop to manipulate it?
If you really need a pid - service status might do it - or running a ps command.
I am writing a perl script to start vnc session.
Firsr I need to rsh to a server then load a module, next execute the "vncserver -otp".
my $mod=`module load turbovnc-1.0.0; vncserver -otp 2> tmp_vnc.log`;
my $launch=`rsh $host /"$mod/"`;
print $launch;
But it does not work, any suggestions??
Thanks!!
Did you mean to use backticks in your first line?
my $mod=`module load turbovnc-1.0.0; vncserver -otp 2> tmp_vnc.log`;
This sets $mod to be the output of this sequence of commands, like running
(module load turbovnc-1.0.0; vncserver -otp 2> tmp_vnc.log) | rsh $host
from the shell. You probably wanted to say
my $mod='module load turbovnc-1.0.0; vncserver -otp 2> tmp_vnc.log';
which will set you up to run those specific commands on the remote host, and execute
rsh $host "module load turbovnc-1.0.0; vncserver -otp 2> tmp_vnc.log"
It also looks like in the rsh command that you are trying to escape the quotation marks with forward slashes. In Perl (and in everything else as far as I know), use a backslash to escape a special character.
my $launch=`rsh $host /"$mod/"`; # / wrong /
my $launch=`rsh $host \"$mod\"`; # \ right \
my $launch=`rsh $host "$mod"`; # right, esc is not reqd in this case
A number of things could be going wrong, but probably the system commands are quietly failing. Either loading the module, starting the vncserver or the rsh. You can manually check for their success or failure by checking $? after each command... or you can use IPC::System::Simple and it will error out if the command fails.
I would start by doing it as a series of shell commands to make sure it works.
Then I'd rewrite the code like so using IPC::System::Simple to do the error checking. Also separating the $mod command into two commands, because I suspect you're getting back the output of running the vncserver, not loading the module.
use strict;
use warnings;
use IPC::System::Simple qw(run capture);
my $host = "something.something";
# Capture the output of loading the module
my $mod = capture('module', 'load', 'turbovnc-1.0.0');
warn "Module output: $mod\n";
# Run the VNC server
run('vncserver -otp 2> tmp_vnc.log');
# Connect to the host
my $launch = capture('ssh', $host, "/$mod/");
warn "ssh output: $launch";
There would seem to be a possibly false assumption that the location of the module on this machine is the same as the location of the module on the remote machine. That or I don't understand what you're doing with $mod.
use Net::SSH::Perl;
my $ssh = Net::SSH::Perl->new('$host',22);
$ssh->login('$user','$pass');
my $out = $ssh->cmd("show clock");
print $out;
I have the above script to have an ssh session using perl but I'm having the error message
"Can't map service name 'ssh' to port number". I'm using Windows OS. Please advise me where I'm wrong.
Try adding ssh to your services file. The services file is located at:
%SystemRoot%\system32\drivers\etc\services
The line that you'll want to add will look like:
ssh 22/tcp # Secure Shell Login