Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Net::SSH::Expect

69 views
Skip to first unread message

Nene

unread,
May 17, 2012, 6:39:56 PM5/17/12
to
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.

Ben Morrow

unread,
May 17, 2012, 7:09:29 PM5/17/12
to

Quoth Nene <rodb...@gmail.com>:
> 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

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

use warnings;

rather than -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...

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

> # 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";

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

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

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.

Ben

Nene

unread,
May 17, 2012, 8:31:05 PM5/17/12
to
On May 17, 7:09 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Nene <rodbas...@gmail.com>:
>
> > 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

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.
>
> > use strict;

It's at the top of the script.
>
> > my $ssh = Net::SSH::Expect->new (
> >             host => "xxxxxxx",
> >             password=> 'xxxxxx',
> >             user => 'xxxxxx',
> >             raw_pty => 1
> >         );
>
> > print "$main::newvar\n", br;  #### It prints here...
>
> 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)
>
> > # now start the ssh process
> > $ssh->run_ssh() or die "SSH process couldn't start: $!";

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.
>
> > print "$main::newvar\n", br; It DOES NOT print  here.....
>
> 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.
>
> Ben

Nene

unread,
May 17, 2012, 8:51:44 PM5/17/12
to
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;

Ben Morrow

unread,
May 17, 2012, 9:29:07 PM5/17/12
to

Quoth Nene <rodb...@gmail.com>:
>
> 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

Nene

unread,
May 17, 2012, 9:42:28 PM5/17/12
to
On May 17, 9:29 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Nene <rodbas...@gmail.com>:
>
>
>
I found the fix.
I had to disable SElinux with:
echo 0 > /selinux/enforce

Thank you everybody.

Tim McDaniel

unread,
May 18, 2012, 12:06:27 PM5/18/12
to
In article <38lg89-...@anubis.morrow.me.uk>,
Ben Morrow <b...@morrow.me.uk> wrote:
>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".

--
Tim McDaniel, tm...@panix.com

Jim Gibson

unread,
May 18, 2012, 3:10:38 PM5/18/12
to
In article <jp5s23$eja$1...@reader1.panix.com>, Tim McDaniel
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.

--
Jim Gibson

Ben Morrow

unread,
May 18, 2012, 4:39:59 PM5/18/12
to

Quoth tm...@panix.com:
$^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, the C part of
IO::Pty specifically checks $^W (which is called PL_dowarn in C) rather
than using the newer XS warning interfaces which honour the 'warnings'
settings of the caller. This is probably simply because the code
predates 'warnings', and noone's bothered to update it.

In fact, most of the command-line flags have an equivalent magic
variable:

-0 $/
-C ${^UNICODE}, though this is readonly after perl startup
-c $^C
-d $^P, though -d does more than just set $^P
-D $^D
-i $^I
-I @INC
-l $\, though -l also does autochomping
-T/-t ${^TAINT}, though this is readonly after perl startup
-w $^W

-[npaFmMuE] can be otherwise easily implemented in Perl; -S and -x are
specific to finding the start of the program and so can't be; -e *can*
be emulated, though it's not entirely straightforward; -[hvV] instruct
perl to do something other than run a Perl program; which leaves just
-[WXU] as switches with no Perl equivalent.

Ben

Tim McDaniel

unread,
May 18, 2012, 10:21:31 PM5/18/12
to
In article <vloi89-...@anubis.morrow.me.uk>,
Ben Morrow <b...@morrow.me.uk> wrote:
>$^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.

--
Tim McDaniel, tm...@panix.com

Ben Morrow

unread,
May 19, 2012, 11:45:08 AM5/19/12
to

Quoth tm...@panix.com:
> In article <vloi89-...@anubis.morrow.me.uk>,
> Ben Morrow <b...@morrow.me.uk> wrote:
> >$^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.

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.

In fact, a plain BEGIN inherits the lexical scope outside it:

use warnings;
my $x;

BEGIN {
# warnings are on here
# $x is visible here
require Foo;
}

## Foo.pm

package Foo;

# warnings are off here
# $x is not visible here

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.

Ben

Tim McDaniel

unread,
May 19, 2012, 7:42:07 PM5/19/12
to
In article <4prk89-...@anubis.morrow.me.uk>,
Ben Morrow <b...@morrow.me.uk> wrote:
>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.

--
Tim McDaniel, tm...@panix.com
0 new messages