Use shell script to check port status on multiple servers
#!/usr/bin/env bash
IP_FILE="${1:-ips.txt}"
PORT=25
CONNECT_TIMEOUT=5
has_cmd() { command -v "$1" >/dev/null 2>&1; }
if [[ ! -f "$IP_FILE" ]]; then
echo "ERROR: Input file not found: $IP_FILE" >&2
exit 1
fi
# Prefer nc (more predictable), else use telnet+timeout
TOOL=""
if has_cmd nc; then
TOOL="nc"
elif has_cmd telnet && has_cmd timeout; then
TOOL="telnet"
else
echo "ERROR: Need nc OR telnet+timeout installed." >&2
exit 1
fi
echo "== SMTP Port 25 Check =="
echo "Hosts file: $IP_FILE | Timeout: ${CONNECT_TIMEOUT}s | Tool: $TOOL"
echo "--------------------------------------------------------"
ok=0; to=0; fail=0; processed=0
while IFS= read -r host; do
host="${host//$'\r'/}" # remove CR (Windows CRLF)
host="$(echo "$host" | xargs)" # trim whitespace
[[ -z "$host" ]] && continue
[[ "$host" =~ ^# ]] && continue
processed=$((processed + 1))
echo "[$processed] Checking $host:$PORT ..."
if [[ "$TOOL" == "nc" ]]; then
out="$(nc -vz -w "$CONNECT_TIMEOUT" "$host" "$PORT" 2>&1)"
rc=$?
if [[ $rc -eq 0 ]]; then
echo " -> CONNECTED"
ok=$((ok+1))
else
if echo "$out" | grep -Eqi "(timed out|timeout)"; then
echo " -> TIMEOUT"
to=$((to+1))
else
echo " -> FAILED"
fail=$((fail+1))
fi
fi
else
out="$(timeout "$CONNECT_TIMEOUT" bash -c "echo QUIT | telnet $host $PORT" 2>&1)"
rc=$?
if [[ $rc -eq 124 ]]; then
echo " -> TIMEOUT"
to=$((to+1))
elif echo "$out" | grep -Eqi "(Connected to|220[ -])"; then
echo " -> CONNECTED"
ok=$((ok+1))
else
echo " -> FAILED"
fail=$((fail+1))
fi
fi
done < "$IP_FILE"
echo "--------------------------------------------------------"
echo "Summary:"
echo " CONNECTED: $ok"
echo " TIMEOUT: $to"
echo " FAILED: $fail"
echo " TOTAL: $processed"