fix: select scan-ip network interface

This commit is contained in:
2026-09-21 19:59:15 +08:00
parent cffe3f01f4
commit 89ad569581
+99 -11
View File
@@ -11,6 +11,7 @@ usage() {
扫描局域网主机:
无参数 ICMP 扫描本网段 .1-.254,并尽力显示名称、MAC 和厂商
检测到多个 IPv4 网卡时会先让你选择扫描源
--identify 额外通过 mDNS 识别设备(macOS,约增加 3 秒)
10.0.0 扫描指定网段前缀
22 扫描本网段 TCP 22 端口
@@ -92,15 +93,101 @@ if [ -n "$1" ] && [ -z "$PORT_SPEC" ] && [ -z "$PREFIX_ARG" ]; then
exit 1
fi
if command -v ip &>/dev/null; then
LOCAL_IP=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1 | head -n 1)
elif command -v ifconfig &>/dev/null; then
LOCAL_IP=$(ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | head -n 1)
else
echo "错误: 找不到 ip 或 ifconfig 命令" && exit 1
fi
list_ipv4_interfaces() {
if [ "$(uname -s)" = "Darwin" ] && command -v ifconfig &>/dev/null; then
ifconfig | awk '
/^[^[:space:]][^:]*:/ {
iface=$1
sub(/:$/, "", iface)
next
}
/^[[:space:]]+inet / {
ip=$2
if (iface !~ /^lo/ && ip != "127.0.0.1" && ip !~ /^169\.254\./) {
print iface "\t" ip
}
}
'
elif command -v ip &>/dev/null; then
ip -o -4 addr show up scope global 2>/dev/null \
| awk '{split($4, address, "/"); print $2 "\t" address[1]}'
elif command -v ifconfig &>/dev/null; then
ifconfig | awk '
/^[^[:space:]][^:]*:/ {
iface=$1
sub(/:$/, "", iface)
next
}
/^[[:space:]]+inet / {
ip=$2
if (iface !~ /^lo/ && ip != "127.0.0.1" && ip !~ /^169\.254\./) {
print iface "\t" ip
}
}
'
else
return 1
fi
}
[ -z "$LOCAL_IP" ] && echo "错误: 未能检测到本地 IP" && exit 1
select_ipv4_interface() {
local iface ip choice entry default_iface default_label index
local candidates=()
while IFS=$'\t' read -r iface ip; do
[ -n "$iface" ] && [ -n "$ip" ] || continue
candidates+=("$iface|$ip")
done < <(list_ipv4_interfaces)
if [ ${#candidates[@]} -eq 0 ]; then
echo "错误: 未能检测到可用的 IPv4 网卡" >&2
return 1
fi
default_iface=""
if [ "$(uname -s)" = "Darwin" ] && command -v route &>/dev/null; then
default_iface=$(route -n get default 2>/dev/null \
| awk '/^[[:space:]]*interface:/{print $2; exit}')
elif command -v ip &>/dev/null; then
default_iface=$(ip route show default 2>/dev/null \
| awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}')
fi
if [ ${#candidates[@]} -gt 1 ]; then
echo "检测到多个可用 IPv4 网卡,请选择扫描源:" >&2
for index in "${!candidates[@]}"; do
entry=${candidates[$index]}
iface=${entry%%|*}
ip=${entry#*|}
default_label=""
[ "$iface" = "$default_iface" ] && default_label=" (默认路由)"
printf ' %d) %s %s%s\n' "$((index + 1))" "$iface" "$ip" "$default_label" >&2
done
while :; do
printf '请选择 [1-%d]: ' "${#candidates[@]}" >&2
IFS= read -r choice || {
echo >&2
echo "错误: 未选择扫描源网卡" >&2
return 1
}
if [[ "$choice" =~ ^[0-9]+$ ]] \
&& [ "$choice" -ge 1 ] \
&& [ "$choice" -le ${#candidates[@]} ]; then
entry=${candidates[$((choice - 1))]}
break
fi
echo "错误: 请输入 1-${#candidates[@]} 之间的编号" >&2
done
else
entry=${candidates[0]}
fi
LOCAL_IFACE=${entry%%|*}
LOCAL_IP=${entry#*|}
}
select_ipv4_interface || exit 1
if [ -n "$PREFIX_ARG" ]; then
PREFIX="$PREFIX_ARG"
@@ -127,7 +214,8 @@ if [ -n "$PORT_SPEC" ]; then
fi
fi
echo "本机 IP: $LOCAL_IP,扫描网段: $PREFIX.1-254"
echo "扫描源网卡: ${LOCAL_IFACE} (${LOCAL_IP})"
echo "本机 IP: ${LOCAL_IP},扫描网段: ${PREFIX}.1-254"
if [ ${#PORTS[@]} -gt 0 ]; then
echo "扫描端口: ${PORTS[*]} (TCP,超时 ${TIMEOUT}s)"
else
@@ -398,7 +486,7 @@ if [ ${#PORTS[@]} -eq 0 ]; then
for i in $(seq 1 254); do
(
ip="$PREFIX.$i"
if ping -c 1 -W 1 -I "$LOCAL_IP" "$ip" >/dev/null 2>&1; then
if ping -c 1 -W 1 -I "$LOCAL_IFACE" "$ip" >/dev/null 2>&1; then
printf '%s 在线\n' "$(format_host "$ip")" >"$RESULT_DIR/$i"
fi
) &
@@ -418,7 +506,7 @@ if ! command -v nc &>/dev/null; then
exit 1
fi
NC_OPTS=(-z -w "$TIMEOUT")
NC_OPTS=(-z -w "$TIMEOUT" -s "$LOCAL_IP")
if [ "$(uname -s)" = "Darwin" ]; then
NC_OPTS+=(-G "$TIMEOUT")
fi