以下脚本使用 nc 命令扫描指定网段内的 SSH 端口(22),输出所有可以连通的主机 IP。
#!/bin/bash
# 检查依赖
if ! command -v nc &> /dev/null; then
echo "错误:未找到 nc 命令,请先安装 netcat(如:apt install netcat-openbsd)"
exit 1
fi
# 显示使用方法
usage() {
echo "用法: $0 <网段>"
echo "示例: $0 192.168.1.0/24"
echo " $0 192.168.1. (自动补全 /24)"
echo " $0 10.0.0.1-50 (范围格式)"
exit 1
}
# 解析网段并生成 IP 列表
generate_ips() {
local input="$1"
local ips=()
# 格式1: 192.168.1.0/24
if [[ "$input" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$ ]]; then
local network="${input%/*}"
local prefix="${input#*/}"
local base="${network%.*}"
local start=1 end=254
# 仅处理常见的 /24,如需其他掩码可自行扩展
if [[ "$prefix" -eq 24 ]]; then
for i in $(seq $start $end); do
ips+=("$base.$i")
done
else
echo "警告:当前脚本仅支持 /24 掩码,将按 /24 扫描" >&2
for i in $(seq $start $end); do
ips+=("$base.$i")
done
fi
# 格式2: 192.168.1. (自动补全 /24)
elif [[ "$input" =~ ^([0-9]{1,3}\.){3}$ ]]; then
local base="${input%?}" # 去掉末尾的点
for i in $(seq 1 254); do
ips+=("$base.$i")
done
# 格式3: 10.0.0.1-50
elif [[ "$input" =~ ^([0-9]{1,3}\.){3}([0-9]{1,3})-([0-9]{1,3})$ ]]; then
local prefix="${input%-*}"
local start="${input##*-}"
local base="${prefix%.*}"
local last_octet="${prefix##*.}"
if [[ "$last_octet" -le "$start" ]]; then
for i in $(seq "$last_octet" "$start"); do
ips+=("$base.$i")
done
else
echo "错误:起始 IP 大于结束 IP" >&2
exit 1
fi
else
echo "错误:不支持的网段格式" >&2
usage
fi
echo "${ips[@]}"
}
# 并发扫描控制
scan_ip() {
local ip="$1"
if nc -z -w 1 "$ip" 22 2>/dev/null; then
echo "$ip SSH 端口开放,可以连通"
fi
}
# 主程序
if [ $# -ne 1 ]; then
usage
fi
NETWORK="$1"
IP_LIST=($(generate_ips "$NETWORK"))
if [ ${#IP_LIST[@]} -eq 0 ]; then
echo "没有生成任何 IP,请检查输入"
exit 1
fi
echo "开始扫描 ${#IP_LIST[@]} 个主机的 22 端口(超时 1 秒)..."
echo "----------------------------------------"
# 并发数限制(可调整)
MAX_JOBS=50
running=0
for ip in "${IP_LIST[@]}"; do
scan_ip "$ip" &
((running++))
if [ $running -ge $MAX_JOBS ]; then
wait -n # 等待任意一个后台任务完成
((running--))
fi
done
wait # 等待所有剩余任务完成
echo "----------------------------------------"
echo "扫描完成"
使用方法
保存脚本(如
scan_ssh.sh)并赋予执行权限:chmod +x scan_ssh.sh运行扫描,支持三种网段格式:
./scan_ssh.sh 192.168.1.0/24 # CIDR 格式(实际按 /24 处理) ./scan_ssh.sh 192.168.1. # 点结尾,自动补全 1-254 ./scan_ssh.sh 10.0.0.1-50 # 范围格式(起始-结束,仅最后一段)输出示例:
开始扫描 254 个主机的 22 端口(超时 1 秒)... ---------------------------------------- 192.168.1.10 SSH 端口开放,可以连通 192.168.1.22 SSH 端口开放,可以连通 ---------------------------------------- 扫描完成
说明
- 使用
nc -z -w 1检测端口:-z仅连接不发送数据,-w 1设置超时 1 秒。 - 并发扫描(默认 50 个任务同时进行),可根据网络环境调整
MAX_JOBS值。 - 若
nc不支持-z(如某些 BSD 版本),可改用nc -w 1 <ip> 22 < /dev/null,但本脚本按常见 Linux 环境编写。 - 如需扫描其他端口(如自定义 SSH 端口),将脚本中的
22替换为相应端口号即可。
简化版本
#!/bin/bash
# 检测 IP 列表文件中的主机是否可 Ping 通,结果同时输出到屏幕和日志文件
# 用法: ./ping_check.sh <ip_list_file> [output_log_file]
# 默认输出文件名(带时间戳)
DEFAULT_LOG_FILE="ping_result_$(date +%Y%m%d_%H%M%S).log"
# 检查参数
if [ $# -lt 1 ]; then
echo "用法: $0 <ip_list_file> [output_log_file]"
echo "示例: $0 ip_list.txt # 自动生成日志文件"
echo " $0 ip_list.txt result.log # 指定日志文件"
exit 1
fi
IP_FILE="$1"
LOG_FILE="${2:-$DEFAULT_LOG_FILE}"
# 检查 IP 列表文件是否存在
if [ ! -f "$IP_FILE" ]; then
echo "错误: 文件 '$IP_FILE' 不存在"
exit 1
fi
# 检查 ping 命令
if ! command -v ping &> /dev/null; then
echo "错误: 未找到 ping 命令,请先安装。"
exit 1
fi
# 清空(或创建)日志文件,并写入开始时间
echo "检测开始时间: $(date '+%Y-%m-%d %H:%M:%S')" | tee "$LOG_FILE"
echo "IP 列表文件: $IP_FILE" | tee -a "$LOG_FILE"
echo "----------------------------------------" | tee -a "$LOG_FILE"
TOTAL=0
REACHABLE=0
UNREACHABLE=0
# 逐行读取 IP 地址
while IFS= read -r ip || [ -n "$ip" ]; do
# 跳过空行和注释行
[[ -z "$ip" || "$ip" =~ ^# ]] && continue
TOTAL=$((TOTAL + 1))
# 发送一个 ping 包,超时 1 秒
if ping -c 1 -W 1 "$ip" &> /dev/null; then
echo "可达 : $ip" | tee -a "$LOG_FILE"
REACHABLE=$((REACHABLE + 1))
else
echo "不可达 : $ip" | tee -a "$LOG_FILE"
UNREACHABLE=$((UNREACHABLE + 1))
fi
done < "$IP_FILE"
echo "----------------------------------------" | tee -a "$LOG_FILE"
echo "检测完成: 总计 $TOTAL, 可达 $REACHABLE, 不可达 $UNREACHABLE" | tee -a "$LOG_FILE"
echo "日志已保存至: $LOG_FILE"
使用方法
保存脚本为 scan_ssh.sh,执行 chmod +x scan_ssh.sh
运行:./scan_ssh.sh 192.168.1.(注意末尾的点)
文档更新时间: 2026-04-14 09:26 作者:月影鹏鹏