Perl 5.8 从 SSH 命令获取标准输出

Posted

技术标签:

【中文标题】Perl 5.8 从 SSH 命令获取标准输出【英文标题】:Perl 5.8 Get Stdout from SSH command 【发布时间】:2014-09-26 21:47:20 【问题描述】:

我需要创建一个适用于CentOS 5.xCentOS 6.x 框的脚本。 CentOS 5.x 使用Perl 5.8 而CentOS 6.x 使用Perl 5.10。目标是能够通过 ssh 进入一个有密钥交换的盒子,然后运行 ​​python -V,以确定默认版本是否为 python 2.6

我猜如果我得到一个适用于 Perl 5.8 的脚本,那么它也适用于 5.10。我在 Net::SSH:Any 方面取得了一些进展,不得不将其丢弃,因为它看起来适用于 Perl 5.12 及更高版本。

我也尝试过IPC::System::Simpleqx,但没有成功捕获输出。

我的一些失败尝试:

失败 1:

use IPC::System::Simple qw(system systemx capture capturex);
my $output = capture("/usr/bin/ssh root\@10.100.10.56 python -V");
print "out: " . $output . "\n";

失败2:

my $output = qx(ssh root\@10.100.10.56 python -V);
print "out: " . $output . "\n";

失败 3:

my @output = qx(ssh root\@10.100.10.56 python -V);
print "@output\n";

我不确定 ssh 的调用是否在玩任何东西,并且迫切需要进行健全性检查。运行命令时,输出显示在屏幕上,但不存储在变量中,我可以对其进行子字符串检查。 $output 变量留空。如果我遗漏了什么,请告诉我。谢谢:)

【问题讨论】:

python -V 可能会写信给STDERR 而不是STDOUT。另外,为什么不直接为 SSH 使用不同的模块,例如 Net::OpenSSH 我查看了 SSHSSH2OpenSSH。我试图简化事情并直接运行命令以使事情正常进行。有没有办法让qx也捕获stderr? 有。见How to capture both STDOUT and STDERR in two different variables using Backticks in Perl。但是,当存在纯 Perl 等效项时,您应该真正避免使用 bacticks/systemNet::OpenSSH 有一个很好的 system 方法,可让您控制 STDINSTDOUTSTDERR 等。 我不知道你在说什么。 Net::OpenSSH 在 5.8.x 上通过了 CPAN Testers 上的所有测试。我认为您只是在查看许可条款,这与模块是否可以在早期 Perl 版本上运行无关。 IIRC, Net::SSH::Any 只需要 perl 5.8。 【参考方案1】:

从 ThisSuitIsBlackNot 的建议中弄清楚了。我找到了Getting STDOUT, STDERR, and response code from external *nix command in perl,它向我展示了如何更新我的代码以获取 stderr,如下所示:

my $output = qx(ssh root\@10.100.10.56 python -V 2>&1);
print "out: " . $output . "\n";

这给了我我需要的东西。谢谢!

【讨论】:

我很高兴我没有那层复杂性也必须与之抗争 :) 可能与 cygwin 一起工作,但将是一个副项目 :) 我的意思是,Python 是跨平台的,因此没有理由将您检查版本的命令限制为单个操作系统。如果您使用 Net::OpenSSH 之类的模块而不是反引号,则不必担心特定于操作系统的引用和 I/O 重定向。 my @cmd = qw(python -V); $ssh->system( stderr_to_stdout => 1 , @cmd) or die $ssh->error; @ThisSuitIsBlackNot:Net::OpenSSH 在 Windows 上不起作用,甚至在 Cygwin Perl 下也不起作用。这是促使我创建 Net::SSH::Any 的主要原因。 @salva 你的意思是它不能在 Windows 上运行,对吗?我只是在谈论连接到远程 Windows 机器。当然,我从来没有尝试过,所以我只能说我的你知道的。 @ThisSuitIsBlackNot,是的,Net::OpenSSH 可以连接到 Windows 机器。 0.62 版还支持引用 Win32 和 cmd.exe 的命令。

以上是关于Perl 5.8 从 SSH 命令获取标准输出的主要内容,如果未能解决你的问题,请参考以下文章

Perl - 从外部进程直接输出到标准输出(避免缓冲)

无法使用 perl 中的系统命令获取已编译 C 程序执行的标准错误

Perl基础命令---文件句柄基础

102 模拟ssh远程执行命令

100 模拟ssh远程执行命令

无法在 cron 中获取远程 ssh 标准输出,但在我的终端中它可以工作