使用Net::SSH::Expect连接JunOS含双引号命令无输出问题求助
解决Net::SSH::Expect与JunOS交互时带双引号命令无输出的问题
嘿,我刚好碰到过类似的问题,咱们一步步来搞定它:
核心问题分析
你手动执行命令没问题,但通过Net::SSH::Expect发送时无输出,主要卡在两个关键点:
- 双引号在Perl字符串和SSH会话中需要正确转义,不然会被提前解析,导致JunOS收到的命令格式乱掉
- 发送命令时没模拟手动敲回车的操作,命令只是传到终端但没真正触发执行
具体解决方案
1. 处理命令中的引号:转义双引号或改用单引号
如果你的命令从文本文件读取,里面的双引号需要转义为\"才能被JunOS正确识别。用Perl正则替换就能批量处理:
# 假设从文件读取的原始命令存在$raw_cmd中 my $cmd = $raw_cmd; $cmd =~ s/"/\\"/g; # 全局替换双引号为转义后的格式
或者更省心的办法:把JunOS命令里的双引号换成单引号,这样完全不用转义,比如:show interfaces diagnostics optics | match 'Laser output power |Laser receiver power'
单引号在JunOS的match命令里同样生效,还能省掉转义的麻烦。
2. 发送命令时添加换行符
手动执行命令时你会敲回车触发执行,所以通过模块发送时也要加上\n:
# 不要只send($cmd),要加上换行触发命令执行 $session->send("$cmd\n");
3. 优化输出捕获逻辑
$session->before()会包含你发送的命令本身和输出结果,你可以过滤掉命令行,只保留实际的设备输出:
my $full_output = $session->before(); # 移除命令行本身的回显(\Q...\E用来转义命令里的特殊字符) $full_output =~ s/^\Q$cmd\E\n//; # 把输出按行拆分存入数组 @{$data->{'output'}} = split /\n/, $full_output;
完整代码示例
把这些修改整合到你的代码里,大概是这样:
# 从文本文件读取命令的示例 my $raw_cmd = do { local $/; open my $fh, '<', 'your_commands.txt' or die "无法打开命令文件: $!"; <$fh> }; chomp $raw_cmd; # 转义双引号(如果用单引号就跳过这一步) my $cmd = $raw_cmd =~ s/"/\\"/gr; # 发送命令并触发执行 $session->send("$cmd\n"); # 等待设备提示符 unless($session->waitfor($device->{promptSSH}, $cmd_timeout)) { $logger->warn("$device->{hostname} ($device->{ip}) : SSH - Echec (Timeout) de la commande $cmd"); $data->{'timeout'} = 1; } # 处理并保存输出 my $full_output = $session->before(); $full_output =~ s/^\Q$cmd\E\n//; @{$data->{'output'}} = split /\n/, $full_output; return $data;
试试这些修改,应该就能正常获取带引号命令的输出了~
内容的提问来源于stack exchange,提问作者Luc Larochelle
相关产品推荐
相关产品推荐

