#!/usr/bin/env bash set -uo pipefail CHARSET='A-Za-z0-9._\-' DEFAULT_LENGTH=32 usage() { cat <<'EOF' Usage: gen-secret [OPTIONS] [LENGTH] Generate a cryptographically random string safe for bash, YAML, JSON, and URLs. Arguments: LENGTH Number of characters (default: 32) Options: -n, --dryrun Preview what would happen -h, --help Show this help EOF } dryrun=false length="" while [[ $# -gt 0 ]]; do case "$1" in -h|--help) usage exit 0 ;; -n|--dryrun) dryrun=true shift ;; -*) echo "Error: Unknown option: $1" >&2 exit 1 ;; *) if [[ -n "$length" ]]; then echo "Error: Too many arguments" >&2 exit 1 fi length="$1" shift ;; esac done length="${length:-$DEFAULT_LENGTH}" if ! [[ "$length" =~ ^[0-9]+$ ]] || [[ "$length" -le 0 ]]; then echo "Error: Length must be a positive integer" >&2 exit 1 fi if $dryrun; then echo "[dryrun] Would generate a ${length}-character secret from charset: [${CHARSET}]" exit 0 fi tr -dc "$CHARSET" < /dev/urandom | head -c "$length" echo