bash Network January 18, 2025

Port Scanner Bash

A simple and efficient port scanner written in Bash. Ideal for quick checks with no external dependencies.

bashnetworkscanports

Description

This Bash script scans open ports on a target host. It uses Bash’s /dev/tcp pseudo-device to test TCP connections with zero external dependencies.

Features

  • TCP port scanning by range
  • Fast mode with configurable timeout
  • Colored output with common service identification
  • No dependencies (pure Bash)

Usage

# Make executable
chmod +x port_scanner.sh

# Scan ports 1-1024
./port_scanner.sh 192.168.1.1 1 1024

# Scan a specific port
./port_scanner.sh example.com 80 80

# Scan all ports
./port_scanner.sh 10.0.0.1 1 65535

Source Code

#!/usr/bin/env bash
#
# port_scanner.sh — Simple TCP port scanner in Bash
# Usage: ./port_scanner.sh <host> <start_port> <end_port> [timeout]
#

set -euo pipefail

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Common services
declare -A SERVICES=(
    [21]="FTP"
    [22]="SSH"
    [23]="Telnet"
    [25]="SMTP"
    [53]="DNS"
    [80]="HTTP"
    [110]="POP3"
    [143]="IMAP"
    [443]="HTTPS"
    [993]="IMAPS"
    [995]="POP3S"
    [3306]="MySQL"
    [5432]="PostgreSQL"
    [6379]="Redis"
    [8080]="HTTP-Alt"
    [8443]="HTTPS-Alt"
    [27017]="MongoDB"
)

# Argument validation
if [[ $# -lt 3 ]]; then
    echo -e "${CYAN}╔══════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║   🔍 Port Scanner Bash v1.0         ║${NC}"
    echo -e "${CYAN}╚══════════════════════════════════════╝${NC}"
    echo ""
    echo -e "Usage: ${GREEN}$0 <host> <start_port> <end_port> [timeout]${NC}"
    echo -e "Example: ${YELLOW}$0 192.168.1.1 1 1024 1${NC}"
    exit 1
fi

HOST="$1"
PORT_START="$2"
PORT_END="$3"
TIMEOUT="${4:-1}"

# Counters
OPEN=0
CLOSED=0
TOTAL=$((PORT_END - PORT_START + 1))

echo -e "${CYAN}╔══════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║         🔍 Port Scanner Bash v1.0           ║${NC}"
echo -e "${CYAN}╠══════════════════════════════════════════════╣${NC}"
echo -e "${CYAN}║${NC} Target   : ${GREEN}${HOST}${NC}"
echo -e "${CYAN}║${NC} Ports    : ${GREEN}${PORT_START}-${PORT_END}${NC} (${TOTAL} ports)"
echo -e "${CYAN}║${NC} Timeout  : ${GREEN}${TIMEOUT}s${NC}"
echo -e "${CYAN}║${NC} Date     : ${GREEN}$(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════╝${NC}"
echo ""

START_TIME=$(date +%s)

for ((port=PORT_START; port<=PORT_END; port++)); do
    # Show progress every 100 ports
    if (( port % 100 == 0 )); then
        PROGRESS=$(( (port - PORT_START) * 100 / TOTAL ))
        echo -ne "\r${YELLOW}[${PROGRESS}%] Scanning... port ${port}/${PORT_END}${NC}    "
    fi

    # Test the port with timeout
    if timeout "$TIMEOUT" bash -c "echo >/dev/tcp/$HOST/$port" 2>/dev/null; then
        SERVICE="${SERVICES[$port]:-unknown}"
        echo -e "\r${GREEN}[OPEN]${NC} Port ${CYAN}${port}${NC}/tcp — ${YELLOW}${SERVICE}${NC}    "
        ((OPEN++))
    else
        ((CLOSED++))
    fi
done

END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

echo ""
echo -e "${CYAN}╔══════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║              📊 Results                     ║${NC}"
echo -e "${CYAN}╠══════════════════════════════════════════════╣${NC}"
echo -e "${CYAN}║${NC} Open ports   : ${GREEN}${OPEN}${NC}"
echo -e "${CYAN}║${NC} Closed ports : ${RED}${CLOSED}${NC}"
echo -e "${CYAN}║${NC} Scan duration: ${YELLOW}${DURATION}s${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════╝${NC}"

Notes

  • This script is designed for quick checks. For professional scanning, use Nmap.
  • The /dev/tcp pseudo-device is not available in all shells — make sure you’re using Bash.
  • The default timeout is 1 second per port. Reduce it to speed up scanning on a local network.