mokky14's IT diary

IT関係の仕事メモ、勉強会の感想など書いてます。

perlでTelnet

perlNet::Telnetモジュールを使用するアプリ作ってみたのでメモ残しとく。

#!/usr/bin/perl

use strict;
use warnings;

use Net::Telnet;

my $host = '127.0.0.1';
my $user = 'hoge';
my $passwd = 'fuga';
my $prompt = '/\[.*\]\$/';

my $t = new Net::Telnet(
                        Timeout=>10,
                        Prompt => $prompt);
$t->open($host);
$t->login($user, $passwd);

my $res = 0;

my @lines = $t->cmd('ls -l /usr');
print @lines;
$res = $t->cmd('echo $?');
print "res:".$res."\n";

# このmkdirは失敗する
$res = $t->cmd('mkdir /usr/abc/def/ghi/');
print "res:".$res."\n";

$t->close;

exit;

newしたときのPromptは、ログインユーザのプロンプトのマッチング文字列を指定する。
ちなみにこのとき使用したユーザのプロンプトは

[~]$ echo $PS1
[\w]$

実行した結果は

[~]$ perl telnet_1.pl
合計 276
drwxr-xr-x   3 root root  4096 10月 23  2012 X11R6
drwxr-xr-x   2 root root 69632  6月  5 09:32 bin
drwxr-xr-x   2 root root  4096  5月 11  2011 etc
drwxr-xr-x   2 root root  4096  5月 11  2011 games
drwxr-xr-x  62 root root  4096  5月 22 16:39 include
drwxr-xr-x   3 root root  4096  2月  8 18:46 java
drwxr-xr-x   6 root root  4096  2月 23  2012 kerberos
drwxr-xr-x  79 root root 32768  6月  5 09:32 lib
drwxr-xr-x 103 root root 49152  6月  5 09:33 lib64
drwxr-xr-x  15 root root  4096  5月 15 17:19 libexec
drwxr-xr-x  15 root root  4096  2月 19 18:54 local
drwxr-xr-x   2 root root 20480  5月 15 17:19 sbin
drwxr-xr-x 252 root root 12288  6月  5 09:32 share
drwxr-xr-x   5 root root  4096  1月 31 10:49 src
lrwxrwxrwx   1 root root    10 10月 23  2012 tmp -> ../var/tmp
res:1
res:1
[~]$ 

ん?なんでコマンドの終了コードが両方とも1になる?
分からんので、マニュアルをちゃんと読んでみたら、

In a scalar context, the characters read from the remote side are discarded and 1 is returned on success. On time-out, eof, or other failures, the error mode action is performed. See errmode().

指定コマンドをリモート投入に成功したら1になるわけで、コマンドそのものの終了ステータスを取れるわけではないのね。勘違いしてた。

ということで、コマンドの成功/失敗を"echo $?"で取得するようにしてみた。

#!/usr/bin/perl

use strict;
use warnings;

use Net::Telnet;

my $host = '127.0.0.1';
my $user = 'hoge';
my $passwd = 'fuga';
my $prompt = '/\[.*\]\$/';

my $t = new Net::Telnet(
            Timeout=>10,
            Prompt => $prompt);
$t->open($host);
$t->login($user, $passwd);

my @lines = $t->cmd('ls -l /usr');
print @lines;
my @ls_result = $t->cmd('echo $?');
print "ls result:".$ls_result[0];

# このmkdirは失敗する
$t->cmd('mkdir /usr/abc/def/ghi/');
my @mkdir_result = $t->cmd('echo $?');
print "mkdir result:".$mkdir_result[0];

$t->close;

exit;

実行した結果

[~]$ perl telnet_1.pl
合計 276
drwxr-xr-x   3 root root  4096 10月 23  2012 X11R6
drwxr-xr-x   2 root root 69632  6月  5 09:32 bin
drwxr-xr-x   2 root root  4096  5月 11  2011 etc
drwxr-xr-x   2 root root  4096  5月 11  2011 games
drwxr-xr-x  62 root root  4096  5月 22 16:39 include
drwxr-xr-x   3 root root  4096  2月  8 18:46 java
drwxr-xr-x   6 root root  4096  2月 23  2012 kerberos
drwxr-xr-x  79 root root 32768  6月  5 09:32 lib
drwxr-xr-x 103 root root 49152  6月  5 09:33 lib64
drwxr-xr-x  15 root root  4096  5月 15 17:19 libexec
drwxr-xr-x  15 root root  4096  2月 19 18:54 local
drwxr-xr-x   2 root root 20480  5月 15 17:19 sbin
drwxr-xr-x 252 root root 12288  6月  5 09:32 share
drwxr-xr-x   5 root root  4096  1月 31 10:49 src
lrwxrwxrwx   1 root root    10 10月 23  2012 tmp -> ../var/tmp
ls result:0
mkdir result:1

意図した終了コードが取れた。