Bash如何将curl输出赋值给变量做ping、telnet检测
Shell脚本捕获curl输出并完成IP可用性校验方案
核心问题修复点
- 原命令
--stderr -i属于参数错误:--stderr后需要指定错误输出路径,-i是打印HTTP响应头的参数,会导致返回内容夹杂响应头,造成awk字段提取错位,是变量赋值失败的核心诱因 - 要将命令输出存入变量,直接使用
变量名=$(完整命令序列)语法即可,所有管道处理逻辑都可以放在$()括号内 - 入参校验需要放在请求发送前,避免未传参数时仍然发起无效API请求
- curl默认会向stderr输出请求进度条,不加处理会污染变量中存储的有效返回内容
修正后可直接运行的完整脚本
#!/bin/bash # 入参校验,未传子网参数直接退出 if [[ -z "$1" ]]; then echo "错误:请传入待查询的子网段作为执行参数" exit 1 fi # 调用API并将处理后的结果存入变量 # 参数说明:-s 开启静默模式不输出进度,--stderr /dev/null 丢弃错误日志,去掉-i参数避免响应头混入正文 api_result=$(curl -s --stderr /dev/null -H "Accept: application/json" -X POST \ -d "query=ip" -d "string=$1" \ -u 'username:password' \ https://device42.xxxxxxxxx/api/1.0/search/ \ --insecure | awk '{print $9,$10,$11}') # 校验API返回是否为可用IP if [[ $(echo "$api_result" | awk '{print $2}') != "Yes" ]]; then echo "API未查询到目标子网下的可用IP,请检查子网参数或API权限" exit 1 fi # 提取目标IP存入独立变量,供后续连通性检测调用 target_ip=$(echo "$api_result" | awk '{print $4}') echo "API返回候选可用IP:$target_ip" # ping连通性检测:发送2个探测包,单包超时2秒 echo "开始ping连通性检测..." ping -c 2 -W 2 "$target_ip" > /dev/null 2>&1 if [[ $? -eq 0 ]]; then echo "检测失败:$target_ip 可响应ping,IP已被占用" exit 1 fi # 端口连通性校验,使用bash内置/dev/tcp实现,无需额外安装telnet check_ports=(22 80 3389) ip_valid=true for port in "${check_ports[@]}"; do echo "开始检测$target_ip:$port 连通性..." (echo >/dev/tcp/"$target_ip"/$port) >/dev/null 2>&1 if [[ $? -eq 0 ]]; then echo "检测失败:$target_ip 端口$port 可连通,IP已被占用" ip_valid=false break fi done if $ip_valid; then echo "全部校验通过,$target_ip 为真实可用IP" # 后续可在此处添加IP分配、写入配置等业务逻辑 else exit 1 fi
补充说明
- 如果坚持使用telnet做端口检测,把循环内的检测逻辑替换为
timeout 2 telnet "$target_ip" $port >/dev/null 2>&1即可,注意加timeout避免telnet长时间挂起 - 所有API返回值在使用前都要做格式校验,避免API鉴权失败、服务报错时返回非预期内容,导致后续逻辑取空值运行出错
- 不推荐使用反引号
`命令`的方式做变量赋值,嵌套场景下转义逻辑复杂,兼容性差,统一用$()即可
内容的提问来源于stack exchange,提问作者Unixcited
相关产品推荐
相关产品推荐

