Perl で ssh 接続してコマンドを実行する方法を調べていたところ、Net::OpenSSH というモジュールを教えてもらったので試してみた。
Perl のインストール
必須ではないが、本題の前に Perlbrew を使って Mac に新しめの Perl を入れておく。
まず Perlbrew をインストールする。 (bash の場合は適宜読み替えて)
$ curl -kL http://install.perlbrew.pl | bash
$ echo "source ~/perl5/perlbrew/etc/bashrc" >> ~/.zshrc
$ . ~/.zshrc
$ perlbrew self-upgrade
入った。
$ perlbrew version
/Users/sho/perl5/perlbrew/bin/perlbrew - App::perlbrew/0.58
新しめの Perl を入れる。
$ perlbrew available
perl-5.17.8
perl-5.16.2
perl-5.14.3
:
$ perlbrew install perl-5.16.2
$ perlbrew switch perl-5.16.2
入った。
$ perl -v
This is perl 5, version 16, subversion 2 (v5.16.2) built for darwin-2level
:
モジュールのインストール
CPAN を用いて、Mac に Net::OpenSSH とそれに必要なモジュールをインストールする。
$ perlbrew install-cpanm
$ cpanm Net::OpenSSH
$ cpanm IO::Pty
使ってみる
ほぼ SYNOPSIS のまんまだが、下記のようなコードを動かしてみた。
$ vi ssh.pl
#!/usr/bin/env perl
use strict;
use Net::OpenSSH;
my $host = 'host.example.com';
my %opt = (
user => 'MyUSER',
password => 'MyPASS',
);
# 接続
my $ssh = Net::OpenSSH->new($host, %opt);
die 'SSH connection failed: ' . $ssh->error if ($ssh->error);
# すぐに結果が返ってくるコマンド
print $ssh->capture('cat /etc/redhat-release');
print "\n";
# 時間がかかるコマンド
my ($rout, $pid) = $ssh->pipe_out('ping -c 5 www.yahoo.co.jp')
or die "pipe_out method failed: " . $ssh->error;
while (<$rout>) { print; }
close $rout;
# exit code を取得
%opt = (
stdout_fh => \*STDOUT,
stderr_fh => \*STDERR
);
my $status = $ssh->test(\%opt, 'test -x /usr/bin/perl');
実行してみると、ちゃんとサーバでコマンドが実行されて、結果が表示される。
$ chmod +x ssh.pl
$ ./ssh.pl
Scientific Linux release 6.3 (Carbon)
PING www.g.yahoo.co.jp (203.216.243.240) 56(84) bytes of data.
64 bytes from f11.top.vip.tnz.yahoo.co.jp (203.216.243.240): icmp_seq=1 ttl=54 time=9.62 ms
64 bytes from f11.top.vip.tnz.yahoo.co.jp (203.216.243.240): icmp_seq=2 ttl=54 time=28.5 ms
64 bytes from f11.top.vip.tnz.yahoo.co.jp (203.216.243.240): icmp_seq=3 ttl=54 time=26.3 ms
64 bytes from f11.top.vip.tnz.yahoo.co.jp (203.216.243.240): icmp_seq=4 ttl=54 time=24.8 ms
64 bytes from f11.top.vip.tnz.yahoo.co.jp (203.216.243.240): icmp_seq=5 ttl=54 time=22.2 ms
--- www.g.yahoo.co.jp ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4031ms
rtt min/avg/max/mdev = 9.626/22.321/28.507/6.672 ms
scp や rsync もできる。
$ssh->scp_put({glob => 1}, 'photos/*.jpg', 'testdir')
or die 'scp failed: ' . $ssh->error;
これはいろいろ捗りそうだ。
コメント