#!/usr/bin/env bash # --- # @file_name: pwgen.sh # @version: 1.0.1 # @description: Generate a passphrase # @author: Jamie Albert (empty_produce) # @author_contact: # @license: GNU Affero General Public License v3.0 (Included in LICENSE) # Copyright (C) 2025, Jamie Albert # --- set -euo pipefail declare -gr WORD_LIST='/usr/share/dict/japg.list' declare -gr DEFAULT_DELIM='-' declare -gi DEFAULT_WORDS=5 # --- # @return_code: [2] Word-list file not found. # @return_code: [3] Required tool 'xclip' not found. # shellcheck disable=1091,1090 # --- setup() { . /usr/local/share/dao/libs/libs_dao.sh [[ -f "${WORD_LIST}" ]] || dao::error 2 "Word-list not found: $WORD_LIST" command -v xclip >/dev/null || dao::error 3 "xclip not found (install xclip)" } # --- # @arg: $1 - Number of words (optional, defaults to DEFAULT_WORDS). # @arg: $2 - Delimiter (optional, defaults to DEFAULT_DELIM). # @return_code: [1] General dao::error (inherits from set -e). # @return_code: [4] Invalid number of words provided. # @return_code: [2] Word-list not found (inherited from setup). # @return_code: [3] xclip not found (inherited from setup). # --- main() { setup declare num_words="${1:-$DEFAULT_WORDS}" declare delim="${2:-$DEFAULT_DELIM}" [[ "${num_words}" =~ ^[1-9][0-9]*$ ]] || dao::error 4 "num_words must be a positive integer" declare -a words mapfile -t words < <(shuf -n "$num_words" "$WORD_LIST") || dao::error 1 "Failed to read words from list" declare i for i in "${!words[@]}"; do words[i]="${words[i]^}" done declare dig_idx=$(( RANDOM % num_words )) words[dig_idx]+=$(( RANDOM % 10 )) declare pass IFS="$delim" printf -v pass '%s' "${words[*]}" || dao::error 1 "Failed to construct passphrase" printf '%s' "$pass" | xclip -selection clipboard || dao::error 1 "Failed to copy passphrase to clipboard" dao::info "Generated password: $pass" dao::info "Password copied to clipboard." } main "$@"