You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:42:29