LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Perl script to SSH into a server, and sudo (https://www.linuxquestions.org/questions/linux-software-2/perl-script-to-ssh-into-a-server-and-sudo-835493/)

jhyland87 09-30-2010 04:58 PM

Perl script to SSH into a server, and sudo
 
Hey guys, so basically, I need to create a perl script to SSH into a list of servers, and run a command as sudo. I tested with this script:

Code:

#!/usr/bin/perl

use Net::SSH::Perl;

$host = "server.name.com";
$user = "jhyland";
$pass = "passwird";

#$ssh = Net::SSH::Perl->new($host, debug => 1, use_pty => 1);
$ssh = Net::SSH::Perl->new($host, use_pty => 1);

$ssh->login($user, $pass);

$cmd = "sudo su -";
$ssh->cmd($cmd);

$cmd = "whoami";
($stdout, $stderr, $exit) = $ssh->cmd($cmd);

print $stdout;

But it would spit out "jhyland" I learned that its because of the TTY limit, which you cant change.

So I tried to use Net::SSH::Expect.. copied from http://search.cpan.org/~bnegrao/Net-...SSH/Expect.pod

Code:

#!/usr/bin/perl

use Net::SSH::Expect;

#
# You can do SSH authentication with user-password or without it.
#

# Making an ssh connection with user-password authentication
# 1) construct the object
my $ssh = Net::SSH::Expect->new (
    host => "server.name.com",
    password=> 'test',
    user => 'jhyland',
    raw_pty => 1
);

# 2) logon to the SSH server using those credentials.
# test the login output to make sure we had success
my $login_output = $ssh->login();
if ($login_output !~ /Last login/) {
    die "Login has failed. Login output was $login_output";
}

# - now you know you're logged in -

# 3) you should be logged on now. Test if you received the remote prompt:
($ssh->read_all(2) =~ />\s*\z/) or die "where's the remote prompt?";

# - now you know you're logged in - #

# disable terminal translations and echo on the SSH server
# executing on the server the stty command:
$ssh->exec("stty raw -echo");

# runs arbitrary commands and print their outputs
# (including the remote prompt comming at the end)
my $ls = $ssh->exec("ls -l /");
print($ls);

my $who = $ssh->exec("who");
print ($who);

# When running a command that causes a huge output,
# lets get the output line by line:
$ssh->send("find /");  # using send() instead of exec()
my $line;
# returns the next line, removing it from the input stream:
while ( defined ($line = $ssh->read_line()) ) {
    print $line . "\n"; 
}

# take a look in what is immediately available on the input stream
print $ssh->peek(0);    # you'll probably see the remote prompt
 
# the last read_line() on the previous loop will not include the
# remote prompt that appears at the end of the output, because the prompt
# doesn't end with a '\n' character. So let's remove the remainder
# prompt from the input stream:
$ssh->eat($ssh->peek(0));  # removes whatever is on the input stream now

# We can also iterate over the output in chunks,
# printing everything that's available at each 1 second:
$ssh->send ("find /home");
my $chunk;
while ($chunk = $ssh->peek(1)) { # grabs chunks of output each 1 second
    print $ssh->eat($chunk);
}

# closes the ssh connection
$ssh->close();

And that doesnt even successfully login. I doubt that the NET::SSH::Expect is my fault, due to the fact that script actually has a typo in it right from the cpan website, so I doubt it was ever even tested.

Any ideas guys?

basically.. I need to shell in, then either sudo httpd -S, or sudo su -; httpd -S

acid_kewpie 10-01-2010 02:10 PM

Can I suggest not doing this this way at all? Check out a tool like func, which will let you run arbitrary scripts on a remote server over a secure authenticated connection. No SSH required. Check it out.


All times are GMT -5. The time now is 11:57 PM.