别再一个个查端口了!这个脚本让你秒出结果

admin 2026-04-13 05:35:09 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档介绍了一个高效的Bash端口检测脚本,支持单个/多个/范围端口输入,使用ss/netstat/bash原生方法检测端口状态,自动识别服务名称并以彩色表格化输出。脚本具有灵活的输入解析、完善的错误处理和良好的兼容性,适用于运维人员快速检查系统端口开放情况。 综合评分: 85 文章分类: 安全工具,运维安全,应用安全,终端安全,其他


cover_image

别再一个个查端口了!这个脚本让你秒出结果

原创

刘军军 刘军军

运维星火燎原

2026年4月10日 09:03 山西

支持单个/多个/范围端口,表格化输出,彩色显示,运维必备神器!

#!/bin/bash

# ==========================================
# 端口检测脚本
# 功能:检测指定端口是否开启,按表格格式输出
# ==========================================

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'# No Color

# 打印彩色消息
print_info() {
    echo-e"${YELLOW}[INFO]${NC}$1"
}

print_success() {
    echo-e"${GREEN}[SUCCESS]${NC}$1"
}

print_error() {
    echo-e"${RED}[ERROR]${NC}$1"
}

# 获取服务名称
get_service_name() {
    local port=$1
    local service_name=""

    # 尝试从 /etc/services 获取服务名称
    service_name=$(grep -w "^[^#]*$port/tcp" /etc/services | head -1 | awk '{print $1}')

    # 如果没有找到,尝试常见端口的服务名
    if [ -z"$service_name" ]; then
        case $portin
            80) service_name="http" ;;
            443) service_name="https" ;;
            22) service_name="ssh" ;;
            21) service_name="ftp" ;;
            25) service_name="smtp" ;;
            110) service_name="pop3" ;;
            143) service_name="imap" ;;
            3306) service_name="mysql" ;;
            5432) service_name="postgresql" ;;
            6379) service_name="redis" ;;
            27017) service_name="mongodb" ;;
            8080) service_name="http-alt" ;;
            8443) service_name="https-alt" ;;
            *) service_name="unknown" ;;
        esac
    fi

    echo"$service_name"
}

# 检测端口状态
check_port() {
    local port=$1

    # 使用多种方法检测端口
    if command -v ss &> /dev/null; then
        # 使用 ss 命令
        ss -tuln | grep-q":$port\b"
    elif command -v netstat &> /dev/null; then
        # 使用 netstat 命令
        netstat -tuln | grep-q":$port\b"
    else
        # 使用 bash 原生方法
&nbsp; &nbsp; &nbsp; &nbsp; timeout&nbsp;1bash-c"cat < /dev/null > /dev/tcp/127.0.0.1/$port"2>/dev/null
&nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;$?-eq0&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo"开启"
&nbsp; &nbsp;&nbsp;else
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo"关闭"
&nbsp; &nbsp;&nbsp;fi
}

# 解析端口输入
parse_ports() {
&nbsp; &nbsp; local&nbsp;input=$1
&nbsp; &nbsp; local&nbsp;ports=()

&nbsp; &nbsp;&nbsp;# 移除所有空格
&nbsp; &nbsp;&nbsp;input=$(echo "$input" | tr -d ' ')

&nbsp; &nbsp;&nbsp;# 按逗号分割
&nbsp; &nbsp;&nbsp;IFS=','&nbsp;read&nbsp;-ra&nbsp;segments <<<&nbsp;"$input"

&nbsp; &nbsp;&nbsp;for&nbsp;segment&nbsp;in"${segments[@]}";&nbsp;do
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;[[&nbsp;"$segment"==&nbsp;*-* ]];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 处理范围端口(如 80-90)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;start=$(echo "$segment" | cut -d'-' -f1)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;end=$(echo "$segment" | cut -d'-' -f2)

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 验证端口范围
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;! [[&nbsp;"$start"=~ ^[0-9]+$&nbsp;&&&nbsp;"$end"=~ ^[0-9]+$&nbsp;&&&nbsp;"$start"-le"$end"&nbsp;&&&nbsp;"$start"-ge1&nbsp;&&&nbsp;"$end"-le65535&nbsp;]];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print_error&nbsp;"无效的端口范围:&nbsp;$segment"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 生成范围内的所有端口
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;((port=start; port<=end; port++));&nbsp;do
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ports+=("$port")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;done
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 处理单个端口
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;! [[&nbsp;"$segment"=~ ^[0-9]+$&nbsp;&&&nbsp;"$segment"-ge1&nbsp;&&&nbsp;"$segment"-le65535&nbsp;]];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print_error&nbsp;"无效的端口:&nbsp;$segment"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fi
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ports+=("$segment")
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fi
&nbsp; &nbsp;&nbsp;done

&nbsp; &nbsp;&nbsp;# 去重并排序
&nbsp; &nbsp; printf&nbsp;"%s\n""${ports[@]}"&nbsp;|&nbsp;sort-n&nbsp;| uniq
}

# 打印表格
print_table() {
&nbsp; &nbsp; local&nbsp;-ndata=$1

&nbsp; &nbsp;&nbsp;# 打印表头
&nbsp; &nbsp; printf&nbsp;"%-8s %-10s %-15s %-10s\n""序号""端口""服务名称""端口状态"
&nbsp; &nbsp; printf&nbsp;"%-8s %-10s %-15s %-10s\n""--------""----------""---------------""----------"

&nbsp; &nbsp;&nbsp;# 打印数据
&nbsp; &nbsp; local&nbsp;index=1
&nbsp; &nbsp;&nbsp;for&nbsp;port&nbsp;in"${data[@]}";&nbsp;do
&nbsp; &nbsp; &nbsp; &nbsp; local&nbsp;service_name=$(get_service_name "$port")
&nbsp; &nbsp; &nbsp; &nbsp; local&nbsp;port_status=$(check_port "$port")

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 根据状态设置颜色
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;"$port_status"="开启"&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;status_color="${GREEN}$port_status${NC}"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;status_color="${RED}$port_status${NC}"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp; &nbsp; &nbsp; printf&nbsp;"%-8s %-10s %-15s %b\n""$index""$port""$service_name""$status_color"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;index=$((index + 1))
&nbsp; &nbsp;&nbsp;done
}

# 主函数
main() {
&nbsp; &nbsp;&nbsp;echo"========================================="
&nbsp; &nbsp;&nbsp;echo" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;端口检测工具"
&nbsp; &nbsp;&nbsp;echo"========================================="
&nbsp; &nbsp;&nbsp;echo""
&nbsp; &nbsp;&nbsp;echo"请输入要检测的端口:"
&nbsp; &nbsp;&nbsp;echo" &nbsp;- 单个端口: 80"
&nbsp; &nbsp;&nbsp;echo" &nbsp;- 多个端口: 80,3306,6379"
&nbsp; &nbsp;&nbsp;echo" &nbsp;- 端口范围: 80-90"
&nbsp; &nbsp;&nbsp;echo" &nbsp;- 混合格式: 22,80-90,3306,6379-6380"
&nbsp; &nbsp;&nbsp;echo""

&nbsp; &nbsp;&nbsp;# 读取用户输入
&nbsp; &nbsp; read&nbsp;-p"请输入端口: "&nbsp;port_input

&nbsp; &nbsp;&nbsp;# 检查输入是否为空
&nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;-z"$port_input"&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; print_error&nbsp;"端口输入不能为空!"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit1
&nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp; print_info&nbsp;"正在解析端口输入..."
&nbsp; &nbsp; local&nbsp;-aports=($(parse_ports "$port_input"))

&nbsp; &nbsp;&nbsp;# 检查是否有有效端口
&nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;${#ports[@]}-eq0&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; print_error&nbsp;"没有有效的端口!"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;exit1
&nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp; print_success&nbsp;"解析到&nbsp;${#ports[@]}&nbsp;个端口"
&nbsp; &nbsp; print_info&nbsp;"开始检测端口状态..."
&nbsp; &nbsp;&nbsp;echo""

&nbsp; &nbsp;&nbsp;# 打印结果表格
&nbsp; &nbsp; print_table ports

&nbsp; &nbsp;&nbsp;echo""
&nbsp; &nbsp; print_success&nbsp;"检测完成!"
}

# 启动脚本
main

脚本功能说明

1. 支持的端口输入格式

| 格式 | 示例 | 说明 | | — | — | — | | 单个端口 | 80 | 只检测 80 端口 | | 多个端口 | 80,3306,6379 | 检测 80、3306、6379 端口 | | 端口范围 | 80-90 | 检测 80 到 90 的所有端口 | | 混合格式 | 22,80-90,3306,6379-6380 | 支持多种格式组合 |

2. 检测端口状态的方法

脚本使用多种方法检测端口:

  • 优先使用 ss 命令(现代系统)
  • 备选使用 netstat 命令(兼容旧系统)
  • 最后使用 Bash 原生的 /dev/tcp 方法(兼容性最好)

3. 服务名称获取

  • 优先从 /etc/services 文件查找
  • 对于常见端口,提供内置的服务名称映射
  • 未识别的端口显示为 unknown

4. 输出格式

  • 使用表格格式输出,清晰易读
  • 开启的端口显示绿色,关闭的显示红色
  • 包含序号、端口、服务名称、端口状态四列

使用方法

1. 保存脚本

将脚本保存为 port_check.sh

2. 添加执行权限

chmod+x port_check.sh

3. 运行脚本

./port_check.sh

4. 输入端口示例

请输入端口: 22,80,443,3306,6379-6380

输出示例

脚本特点

  1. 灵活的输入格式:支持单个、多个、范围、混合格式
  2. 强大的检测能力:使用多种方法检测端口,兼容性好
  3. 智能的服务识别:能自动识别常见服务的名称
  4. 美观的输出格式:表格化输出,颜色区分状态
  5. 完善的错误处理:对无效输入有良好的错误提示
  6. 可扩展性强:代码结构清晰,易于扩展新功能

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:运维星火燎原 刘军军 刘军军《别再一个个查端口了!这个脚本让你秒出结果》

黑客.skill 网络安全文章

黑客.skill

文章总结: 黑客技能库是一个为AI助手设计的网络安全知识工程框架,包含50个核心模块和54个子模块,覆盖Web安全、后渗透、二进制安全等完整攻防体系。项目采用弱
评论:0   参与:  0