Last active
June 20, 2023 22:35
-
-
Save CastleCorp/d90c569eef1660440558df73e10564b3 to your computer and use it in GitHub Desktop.
Check if one or all TLDs are available for your domain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Script by Parker Thomas (@Castlecorp) | |
# /$$$$$$$ /$$$$$/$$$$$$$$ | |
# | $$__ $$|__ $|__ $$__/ | |
# | $$ \ $$ | $$ | $$ | |
# | $$$$$$$/ | $$ | $$ | |
# | $$____/$$ | $$ | $$ | |
# | $$ | $$ | $$ | $$ | |
# | $$ | $$$$$$/ | $$ | |
# |__/ \______/ |__/ | |
# | |
# Search for open domain names | |
# | |
# boilerplate c/o @xero | |
#----------------------------------------------------------------------------- | |
# helper functions | |
#----------------------------------------------------------------------------- | |
# update this function to gracefully cleanup execution | |
clean_exit() { | |
# grab real error code | |
err=$? | |
# reset traps for all signals to not interrupt destructor logic | |
trap '' EXIT HUP INT QUIT PIPE TERM | |
# add calls to any cleanup functions here | |
clean_tempfiles | |
# exit with the appropriate code | |
exit $err | |
} | |
# update this handler to match your options | |
usage() { | |
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" | |
printf "usage: %s <DOMAIN> [-t|-m|-j]" "$me" | |
echo " <DOMAIN>: string to use as the domain name" | |
echo " -t: a single TLD to check" | |
echo " -m: Machine readable - only output available domains" | |
echo " -j: Number of jobs to run in parallel. Default is 3" | |
} | |
# check if required commands/bins exist | |
function installed() { | |
builtin type -P "$1" &> /dev/null | |
# shellcheck disable=SC2181 | |
[[ $? -ne 0 ]] && return 1 | |
if [[ $# -gt 1 ]]; then | |
shift # we've just checked the first one | |
installed "$@" | |
fi | |
} | |
function requirements() { | |
installed "$@" || { | |
for dep in "${deps[@]}" | |
do | |
if ! command -v "$dep" > /dev/null; then | |
echo "$dep is not installed." | |
fi | |
done | |
exit 1; | |
} | |
} | |
# main application logic | |
#----------------------------------------------------------------------------- | |
function checkArgs() { | |
# Set required domain arg | |
if [ $# -lt 1 ]; then usage; fi | |
NAME="$1" | |
shift | |
# Set defaults | |
MACHINE_READABLE=false | |
JOBS=3 | |
# Parse optional flags | |
while getopts 'tmj' opt; do | |
case "$opt" in | |
t) | |
TLDs=$2 | |
shift 2 | |
;; | |
m) | |
MACHINE_READABLE=true | |
shift | |
;; | |
j) | |
JOBS="$3" | |
;; | |
*) | |
usage | |
;; | |
esac | |
done | |
} | |
# Download TLDs and save to a tempfile for reference | |
function getTLDs() { | |
TLDs=$(mktemp /tmp/TLDs.XXXX) | |
curl -s https://data.iana.org/TLD/tlds-alpha-by-domain.txt | tail -n +2 >> "$TLDs" | |
} | |
# Parameters: domain name and TLD | |
function resolveDomain() { | |
local name=$1 | |
local ending=$2 | |
local domain="$name"."$ending" | |
# Grep the whois result to see if it is taken | |
if whois "$domain" | grep -Eq \ | |
'^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri' | |
then # Not taken -> echo it | |
echo "$domain" | |
fi | |
} | |
# If we made a tempfile, rm it | |
function clean_tempfiles() { | |
if [ -f "$TLDs" ]; then rm -f "$TLDs"; fi | |
} | |
# Main loop | |
function main() { | |
deps=("whois" "curl" "parallel") | |
requirements "${deps[@]}" | |
checkArgs "$@" | |
if [ -z "$TLDs" ]; then getTLDs; # If a TLD isn't specified, get the full list | |
else | |
RESULT=$(resolveDomain "$NAME" "$TLDs") # If a TLD is specified, just check that one domain | |
if [ -z "$RESULT" ]; then echo "Domain not available"; else echo "$NAME.$TLDs is available"; fi | |
clean_exit | |
fi | |
if [ "$MACHINE_READABLE" == "false" ]; then echo "Available domains:"; fi | |
export -f resolveDomain # Allow the resolveDomain function to be used by parallel | |
parallel --jobs "$JOBS" resolveDomain "$NAME" ::: "$(cat "$TLDs")" # Run resolveDomain on all TLDs `multithreaded` | |
clean_exit | |
} | |
# runtime setup | |
#----------------------------------------------------------------------------- | |
# fail fast w/ proper exit codes | |
set -eo pipefail | |
# global error handler | |
trap clean_exit EXIT HUP INT QUIT PIPE TERM | |
# Run it | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment