perlでNet::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
意図した終了コードが取れた。