#!/bin/bash # Create a temporary directory and store its path in the TmpDir variable. # Set up a trap to automatically remove this directory when the script exits. export TmpDir="$(mktemp -d)" && trap "rm -rf $TmpDir" EXIT # Parse command-line options. # The script doesn't currently support any options, so it just shows a usage message if any are provided. while getopts ":" opt; do case "${opt}" in \?) echo "Usage: $(basename $0) [<target> <port>]"; exit ;; # Show usage message and exit if an invalid option is given. esac done shift "$((OPTIND-1))" # Shift positional parameters to handle remaining arguments after options. # Set the target and port from the command-line arguments or prompt the user if not provided. target="$1" port="$2" [[ -z "$target" ]] && read -p "Target: " target # Prompt for target if not provided. [[ -z "$port" ]] && read -p "Port #: " port # Prompt for port if not provided. # Attempt to connect to the specified target and port. # Timeout after 3 seconds and redirect any errors to a temporary file. timeout 3s bash -c ': 2> >(head -1 > ${TmpDir}/err) </dev/tcp/'"${target}/${port}" # Check the exit status of the connection attempt and provide appropriate feedback. case $? in 0) echo "Open" ;; # Connection was successful. 124) echo "Connection attempt timed out." ;; # The connection attempt timed out. *) ERR="$(sed 's|bash: [^:]*: ||' "${TmpDir}/err")" # Extract the error message from the temporary file. case "$ERR" in "Connection refused") echo "Closed" ;; # Connection was refused, meaning the port is closed. "No route to host") echo "Filtered" ;; # No route to the host, likely indicating a filtered port. *) echo "$ERR" ;; # Display any other error messages. esac ;; esac