0

リモートサーバーと通信するためのスクリプトを書いています。「ls」や「find / |grep foo」などの基本的なシェル コマンドの送信方法を理解しています。しかし、私は反対側でインタラクティブなアプリケーションを実行しています。

$ssh->shell を呼び出すと、リモート サーバーからプロンプトが表示されるので、SSH がこのプロンプトを受信して​​いることがわかります。しかし、スクリプトがシェルでブロックされているため、何もできません。

2 つのハンドラーをインストールしました。スクリプトを使用して基本的な ssh ホストに接続し、シェル コマンドを実行すると、応答がハンドラーに配信されるので、問題がないことがわかります。したがって、実行中のアプリケーションからのプロンプトがこれらに送信されることを期待していましたが、そうではありません。

#!/usr/bin/perl -w
use strict;    
use Net::SSH::Perl;    

my $host = 'rt.olsendata.com';
my $user = 'rtdemo';
my $pass = 'rtdemo';    
my %params = ('debug' => 1,'protocol' => 2);
my $ssh = Net::SSH::Perl->new($host, %params);

$ssh->register_handler("stderr", sub{ 
            my ($ssh, $packet) = @_;
            receiveerrors($packet);
        });
$ssh->register_handler("stdout", sub{ 
            my ($ssh, $packet) = @_;
            receivedata($packet);
        });
my ($output, $errors, $exit) = $ssh->login($user, $pass);

この時点で、「1」を送信してプロンプトに応答する必要があります。しかし、これはリモート ホストによって、プロンプトへの応答ではなく、シェル コマンドとして解釈されます。「h: 1: そのようなファイルまたはディレクトリはありません」というエラーが返されます。

試してみたい場合は、コードの先頭にあるデモ ssh アカウントを使用できます。公開されています。

編集:Expect がこの問題を解決することはわかっていますが、Expect で register_handler() に相当するものを見つけることができませんでした。私はこれで正しいですか?

4

2 に答える 2

0

最も簡単な解決策は、Net::SSH::Expect です。以下はコードです。ログインするとすぐに、プロンプトに応答して「1」を送信する必要があります(「1」が必要な選択肢です)。次に、別のプロンプトが表示されます。デフォルト値が必要なので、\n を送信します。次に、入力を1行ずつ永遠に読みたいと思います。それは魅力のように機能します。

    my $ssh = Net::SSH::Expect->new (
        host => $host,
        user => $user,
        password=> $pass,
        raw_pty => 1
    );
    my $login_output = $ssh->login();
    my $prompt = $ssh->exec("1");
    my $line;
    $ssh->send("\n");
    while ( defined ($line = $ssh->read_line()) ) {
        print "$line\n"; 
    }
于 2013-08-08T19:56:33.663 に答える