使用while read循环时出现ambiguous redirect错误求助
解决while read脚本中的"ambiguous redirect"错误
问题场景
我尝试用while read处理逗号分隔的名称、路由器及IP地址表格,计划通过SSH登录对应路由器执行BGP路由命令并提取IP写入文件,但运行脚本时出现ambiguous redirect错误。
原脚本代码
grep -v '^#' /opt/pp1/projectprefixed/peeringinfo > /opt/pp1/projectprefixed/$DATE/peeringinfo.conf ip_regex='([0-9]{1,3}\.){3}[0-9]{1,3}' while IFS=, read NREN router1 peering do if [ ! -f /opt/pp1/projectprefixed/$DATE/recFromNRENList/$router1 ] then ssh -q -n -o StrictHostKeyChecking=no srv_oc_scripts@$router1 "show route recieve-protocol bgp" | grep -o "$ip_regex" > peeringsReceived fi done < $router1
表格内容示例
NAME1,mx1.ROUTER1,192.168.1.1 NAME2,mx1.ROUTER2,192.168.65.7
错误原因分析
- 重定向目标模糊:
done < $router1中的$router1是循环内部变量,脚本执行到循环开头时该变量还未赋值,Shell无法确定要读取哪个文件,直接触发ambiguous redirect错误。 - 输出文件路径不合理:
> peeringsReceived使用相对路径,所有路由器的结果会覆盖同一个文件,且不符合脚本中判断/opt/pp1/projectprefixed/$DATE/recFromNRENList/$router1是否存在的逻辑。 - BGP命令拼写错误:
show route recieve-protocol bgp里的recieve是拼写错误,正确应为receive,会导致路由器端命令执行失败。 - 缺失目录检查:未提前确认
$DATE和recFromNRENList目录是否存在,可能导致写入文件时因目录缺失报错。
修正后的脚本
# 提前创建目标目录,-p参数确保父目录不存在时一并创建 mkdir -p /opt/pp1/projectprefixed/$DATE/recFromNRENList # 过滤注释行生成配置文件 grep -v '^#' /opt/pp1/projectprefixed/peeringinfo > /opt/pp1/projectprefixed/$DATE/peeringinfo.conf ip_regex='([0-9]{1,3}\.){3}[0-9]{1,3}' # read添加-r选项,避免反斜杠被转义 while IFS=, read -r NREN router1 peering do target_file="/opt/pp1/projectprefixed/$DATE/recFromNRENList/$router1" if [ ! -f "$target_file" ]; then # 修正BGP命令拼写,结果写入对应路由器的目标文件 ssh -q -n -o StrictHostKeyChecking=no srv_oc_scripts@$router1 "show route receive-protocol bgp" | grep -o "$ip_regex" > "$target_file" fi done < /opt/pp1/projectprefixed/$DATE/peeringinfo.conf
关键修正点说明
- 将循环的输入源改为明确的
peeringinfo.conf文件,解决变量未初始化导致的模糊重定向问题。 - 把输出文件改为每个路由器对应的独立路径,避免结果覆盖,同时匹配脚本的文件存在判断逻辑。
- 修正BGP命令的拼写错误,确保路由器能正确执行命令。
- 新增
mkdir -p命令确保目标目录存在,避免写入失败。 read命令添加-r选项,保留输入中的反斜杠字符,避免意外转义。
内容的提问来源于stack exchange,提问作者Navar0ne
相关产品推荐
相关产品推荐

