Net::SSH::Expect


N

Nene

My variable $main::newvar , which holds a very long command will not
print to screen after '$ssh->run_ssh() or die "SSH process couldn't
start: $!";'

#!!/usr/bin/perl -w
use strict;

my $ssh = Net::SSH::Expect->new (
host => "xxxxxxx",
password=> 'xxxxxx',
user => 'xxxxxx',
raw_pty => 1
);


print "$main::newvar\n", br; #### It prints here...


# now start the ssh process
$ssh->run_ssh() or die "SSH process couldn't start: $!";

$ssh->waitfor('\[xxxxxxx\@a_box:Standby\].* \#', 3) or die "prompt not
found after 3 second";

print "$main::newvar\n", br; It DOES NOT print here.....

Any help will be greatly appreciated.
 
Ad

Advertisements

N

Nene

Correct, It's a typo, I just copied and pasted the code that is giving
me trouble.
That's not what a ~! line looks like. Also, you want

    use warnings;

Ok, thanks.
rather than -w.

It's at the top of the script.
Where does 'br' come from? Is this a CGI script? Please post complete
programs.

It is a CGI script (use CGI is at the top of the page)
The variable doesn't print after the run_ssh command too.
$ssh->waitfor('\[xxxxxxx\@a_box:Standby\].* \#', 3) or die "prompt not
found after 3 second";
The 'waitfor' is not an issue here, tested.
[I *do* hope that # doesn't indicate you're logging in as root with a
password kept in a CGI script...]

I'm not.
If this *is* a CGI script, then probably what happened is that the
->waitfor failed, the script died, and the error is in a server error
log somewhere where you haven't found it. You may find CGI::Carp
helpful, at least during development.

It's not the waitfor command, it doesn't produce an error, it is
authenticating and I'm able to run system commands.
 
N

Nene


Correct, It's a typo, I just copied and pasted the code that is giving
me trouble.


That's not what a ~! line looks like. Also, you want
    use warnings;

Ok, thanks.


rather than -w.

It's at the top of the script.


Where does 'br' come from? Is this a CGI script? Please post complete
programs.

It is a CGI script (use CGI is at the top of the page)



The variable doesn't print after the run_ssh command too.


$ssh->waitfor('\[xxxxxxx\@a_box:Standby\].* \#', 3) or die "prompt not
found after 3 second";

The 'waitfor' is not an issue here, tested.


[I *do* hope that # doesn't indicate you're logging in as root with a
password kept in a CGI script...]

I'm not.


If this *is* a CGI script, then probably what happened is that the
->waitfor failed, the script died, and the error is in a server error
log somewhere where you haven't found it. You may find CGI::Carp
helpful, at least during development.

Ok, I found the error it's producing: Cannot open a pty at /usr/local/
share/perl5/Net/SSH/Expect.pm line 120
I have installed: IO::pty is up to date (1.10).

Below is the Expect.pm


116 # this sets the ssh command line
117 my $ssh_string = $self->{binary} . " $flags $user\@
$host";
118
119 # creating the Expect object
120 my $exp = new Expect();
121
122 # saving this instance
123 $self->{expect} = $exp;
 
N

Nene

Quoth Nene <[email protected]>:


Ok, I found the error it's producing:  Cannot open a pty at /usr/local/
share/perl5/Net/SSH/Expect.pm line 120
I have installed: IO::pty is up to date (1.10).

This error appears to come from IO::pty, if pty_allocate fails.
pty_allocate is an XS function, but it looks to me as though if it's
going to fail it should produce some warnings telling you exactly what
went wrong. Is there anything like that (look for 'pty_allocate' in the
error log)? It's possible you need to turn on global warnings to see
these, rather than 'use warnings' (this, IMHO, is a flaw in IO::pty).

To check this is the problem, run this as a CGI script:

    use warnings;
    use IO::pty;

    my @warns;
    $SIG{__WARN__} = sub { push @warns, $_[0] };
    $^W = 1; # turn on the global warnings flag

    my ($ptyfd, $ttyfd, $ttyname) = IO::pty::pty_allocate();
    my $warns = join "", map "[$_]", @warns;

    print <<CGI;
    Content-type: text/plain

    ptyfd:      [$ptyfd]
    ttyfd:      [$ttyfd]
    ttyname:    [$ttyname]
    warnings:   $warns
    CGI

If this were working properly, $ptyfd and $ttyfd should be small
integers; ttyname should be a convincing name for a tty on your system;
and there should be no warnings. If you get different results, post
them.

Ben

I found the fix.
I had to disable SElinux with:
echo 0 > /selinux/enforce

Thank you everybody.
 
T

Tim McDaniel

It's possible you need to turn on global warnings to see
these, rather than 'use warnings' (this, IMHO, is a flaw in IO::pty).

To check this is the problem, run this as a CGI script:

use warnings; ....
$^W = 1; # turn on the global warnings flag

Would you please explain further? I've never used $^W, and from the
few references I've seen and even the perlvar doc, I thought that it
was equivalent to "use warnings".
 
J

Jim Gibson

Tim McDaniel said:
Would you please explain further? I've never used $^W, and from the
few references I've seen and even the perlvar doc, I thought that it
was equivalent to "use warnings".

From 'perldoc perlvar':

"$WARNING
$^W The current value of the warning switch, initially true if -w
was used, false otherwise, but directly modifiable. (Mnemonic:
related to the -w switch.) See also warnings."

Looks to me like it is more akin to having '-w' in your shebang line,
so it turns on warnings in use'd modules.
 
Ad

Advertisements

T

Tim McDaniel

$^W is equivalent to the -w flag, rather than to 'warnings'. (In fact,
all the -w flag does is set $^W to 1.) While 'warnings' is usually
preferable, since its effects are lexically scoped,

I guess things don't percolate down into used modules. At a quick
glance, I don't see where perlfunc use or require say that it's done
in a separate lexical scope in which the user/requirer is invisible,
unless BEGIN (done by use) does it.

Thank you for the explanation.
 
Ad

Advertisements

T

Tim McDaniel

It's exactly the same as 'my' variables not being visible in required
files. It's not to do with the BEGIN: 'do', 'require' and 'use' all
start a fresh lexical scope, with no lexical variables visible and
'strict', 'warnings' and 'feature' all off. ....
That's what the 'lexical' bit means: 'lexical' means 'to do with
text', and a lexical scope only extends over the bits of code which
are textually inside it.

OK. I had been thinking of "do" being like, for example, "#include"
in C or "eval" in perl, but it's not. I had tried to look this up for
myself in "require" and "use" in perlfunc, but not "do". Having just
done so, I see

do 'stat.pl';

is just like

eval `cat stat.pl`;

except that ... It also differs in that code evaluated with "do
FILENAME" cannot see lexicals in the enclosing scope; "eval
STRING" does.

Thanks for pointing me at the final bit of the docco.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top