【问题标题】:How do I send a password to a command I start with Perl's Expect.pm?如何向以 Perl 的 Expect.pm 开头的命令发送密码?
【发布时间】:2013-05-29 15:44:41
【问题描述】:

我有以下脚本,

#!/usr/bin/perl

use strict;
use warnings;
use Net::SSH::Perl;
use Expect;

my $logs = "logs";
open(LOG,'>>',"$logs") or die "can't logs $!\n";

my $domain = 'domain.com';
my @host = qw/host/;

foreach my $host (@host) {
   my $cmd = "passwd user1";
   my $sshost = join('.', $host, $domain);
   my $ssh = Net::SSH::Perl->new("$sshost");
   $ssh->login('root');
   $ssh->debug();
   my ($stdout, $stderr, $exit) = $ssh->cmd($cmd);
   print LOG $stdout,"\n";
}

现在我的问题是在执行$cmd 之后我不知道如何使用Expect 发送密码,是时候输入密码了。 $stdin 在这种情况下不起作用,因为我们使用的是 HPUX。

感谢任何指导和示例,阅读 Expect 文档对我没有任何帮助。

【问题讨论】:

    标签: perl expect


    【解决方案1】:

    不幸的是,我认为这是不可能的。但是,Net::SSH::Expect 似乎可以为所欲为。

    【讨论】:

    • 是的,似乎在它的概要中,这确实是我需要的,不幸的是无法在此服务器上安装它。
    【解决方案2】:

    我总结一下:需要Expect,ssh模块没用。

    我会更准确地说:如果我理解你的源代码,你的要求,在人类方面,是这样的:登录到一个 Unix 主机集合并使用 passwd(1) 来更新 root 的密码。我有这个权利吗?

    我预计各方都会感到沮丧,因为这个问题的变体已经得到了权威的回答,至少有二十年了。这不是对你的反思,因为我知道找到正确答案是多么困难。

    虽然 Net::SSH 是一个很好且有价值的模块,但它对我理解为您的需求的解决方案没有任何帮助。你需要 Expect。

    事实证明,基于 Tcl 的 Expect 的标准发行版包含一个解决您的情况的示例。在 http://www.ibm.com/developerworks/aix/library/au-expect/ > 中查看 passmass 的描述。

    当然,可以在 Expect.pm 中编写相同的功能。不过,在我展示这一点之前,我先询问最初的提问者 lupin,确认我正在满足他的真正要求。

    【讨论】:

    • 登录到服务器列表,因此我使用 Net::SSH::Perl 然后更新用户的密码(不是 root)。
    • 我上面提到的密码接近了。 Net::SSH 确实不是解决方案的一部分。 lupin,你想要更多的细节,比如 passmass(基于 Tcl)或 Expect.pm(基于 Perl)吗?您正在更新主机集合中的哪些用户的密码?
    • 事情变得有些混乱——也就是说,很困惑。我同意 Net::SSH::Expect 具有足够的功能来实现类似 passmass 的功能。我不明白 lupin 的明显限制是 Net::SSH::PerlExpect.pm 可以安装在他的服务器上,但是 Net::SSH: :期望不能。目前我不知道 lupin 可以使用哪种工具组合(Perl 和一些模块,但不是其他模块?Tcl?)。
    • 因此已经安装了 2 个模块(Net::SSH::Expect/Expect.pm),限制是我无法安装另一个模块,原因是:
    • *) 不允许,我不拥有这台服务器 *) 所以我需要尽可能使用 Net::SSH::Perl 和 Expect.pm
    【解决方案3】:

    我想我在使用 cisco 路由器进入特权 exec 模式时遇到了类似的问题,它在调用“en”时同样要求输入密码。我用一个特殊的子程序解决了这个问题:

    sub enable { my ($expect_session, $password) = @_;
      $expect_session->send("en\n");
      $expect_session->expect($timeout,
        [ qr/[Pp]assword:/,
        sub {
        my $expect_session = shift;
        $expect_session->send("$password","\n");
        exp_continue;
      } ],
    
        -re => $prompt,
     );
    }
    

    但我认为问题在于您没有按照预期使用 Perl 的 Expect。创建一个 Expect 会话来管理 SSH 连接,然后通过它发送命令。你根本不需要 Net::SSH:Perl。这是我的 $expect_session 定义:

      my $expect_session = new Expect();
      $expect_session->log_stdout(0);  # let's keep things quiet on screen; we only want command output.
      $expect_session->log_file(".expectlog");
    
      $expect_session->spawn("/usr/bin/ssh -o StrictHostKeyChecking=no $username\@$host")
       or die ("\nfor some reason we can't establish an SSH session to $host.\n
                  it's something to do with the spawn process: $!\n");
    

    可能缺少一些部分,但希望这会让您朝着正确的方向前进。这是一个复杂的模块,我不完全理解。我祝你好运,让它做你想做的事。

    【讨论】:

    • 检查 Net::OpenSSH。它负责 SSH 连接,并且可以轻松地与 Expect 进行互操作。
    【解决方案4】:

    Net::OpenSSH 可以与Expect 结合使用,以轻松实现。

    实际上,模块分发包含一个 sample script 就是这样做的!

    【讨论】:

      猜你喜欢
      • 2011-05-23
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 2017-06-17
      • 2016-05-15
      • 1970-01-01
      相关资源
      最近更新 更多