我建议不要在 perl 代码中使用系统 ssh 命令,原因如下:
- 它使解析输出变得困难
- 错误处理变得困难
- 编程灵活性较低
而是使用 CPAN 库,例如Net::SSH::Perl 用于从 Perl 代码触发 SSH 命令。
使用这个模块打开一个shell很简单,如下所述:
$ssh->shell
Opens up an interactive shell on the remote machine and connects it to your STDIN. This is most effective when used with a pseudo tty; otherwise you won't get a command line prompt, and it won't look much like a shell. For this reason--unless you've specifically declined one--a pty will be requested from the remote machine, even if you haven't set the use_pty argument to new (described above).
This is really only useful in an interactive program.
In addition, you'll probably want to set your terminal to raw input before calling this method. This lets Net::SSH::Perl process each character and send it off to the remote machine, as you type it.
To do so, use Term::ReadKey in your program:
use Term::ReadKey;
ReadMode('raw');
$ssh->shell;
ReadMode('restore');
下面是一个简单的示例,它演示了使用同一个模块来触发和解析命令输出是多么容易:
use Net::SSH::Perl;
my $ssh = Net::SSH::Perl->new($host);
$ssh->login($user, $pass);
my($stdout, $stderr, $exit) = $ssh->cmd($cmd);
指向 Net::SSH::Perl cpan 文档的链接:http://search.cpan.org/~schwigon/Net-SSH-Perl-1.42/lib/Net/SSH/Perl.pm
我更喜欢使用的另一个模块是 Net::OpenSSH: http://search.cpan.org/~salva/Net-OpenSSH-0.70/lib/Net/OpenSSH.pm
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($host);
$ssh->error and
die "Couldn't establish SSH connection: ". $ssh->error;
$ssh->system("ls /tmp") or
die "remote command failed: " . $ssh->error;
my @ls = $ssh->capture("ls");
$ssh->error and
die "remote ls command failed: " . $ssh->error;
my ($out, $err) = $ssh->capture2("find /root");
$ssh->error and
die "remote find command failed: " . $ssh->error;
my ($rin, $pid) = $ssh->pipe_in("cat >/tmp/foo") or
die "pipe_in method failed: " . $ssh->error;
print $rin "hello\n";
close $rin;