pwg (Yet Another Password Generator)
This generates random passwords from an in-built list of words, in this case all the 3 to 5 letter words made only of standard letters in the default Debian/Mint/Ubuntu English dictionary1). It defaults to a single 12 or more character PW, but you can specify longer or shorter, and multiples with two numbers. Running pwg 20 5 produces;
steve@spearmint:~$ pwg 20 5 Nicks-Edger4Busy%Axed Fiji4Torus*Low6Ewes@Slack Scold3Owned$Ekes8Hobby Palm8Feb_Quite4Aped%Bodes Puff%Bass0CATV_Claim6Sent
#!/bin/bash # Words between 3 and 5 characters # grep -E '^[A-Za-z]{3,5}$' /usr/share/dict/words >> pwg # Above gets only words with easily typed characters # # SRJ 2026-03-29 based on https://www.henriaanstoot.nl/2018/09/14/password-generator-dutch/ # Self="$(dirname ${0})/$(basename ${0})" # Minimum length of Pass Len=12 # If a number was passed as an argument, set length to it [[ ${1} == ?(-)+([0-9]) ]] && Len=${1} Count=1 # If two numbers are passed in, give a list of that many passphrases [[ ${2} == ?(-)+([0-9]) ]] && Count=${2} True=1 False=0 Sym='!@#$%^&*-_' Num='1234567890' SymCnt=${#Sym} NumCnt=${#Num} Loop=1 while [ ${Loop} -le ${Count} ] do TorF=$(( RANDOM % 2 )) # Below deletes from the begining of the script up to and including # the #WORDS line, then sends the rest of the lines to the shuf # command that emits a single word. First=$(sed '1,/^#WORDS$/d' ${Self} | shuf -n 1 ) # Below is a bash builtin that capitalizes the first letter, so # word becomes Word. String=${First^} while [ ${#String} -le ${Len} ] do if [ ${TorF} -eq ${True} ]; then TorF=${False} String+="${Sym:$(($RANDOM%${SymCnt})):1}" else TorF=${True} String+="${Num:$(($RANDOM%${NumCnt})):1}" fi This=$(sed '1,/^#WORDS$/d' ${Self} | shuf -n 1 ) String+=${This^} done echo ${String} ((Loop++)) done exit 0 #WORDS
After you copy and paste the above, then add a dictionary to the end of the script with;
grep -E '^[A-Za-z]{3,5}$' /usr/share/dict/words >> pwg
On my laptop at home, that produces a list of 10756 words, the password 'Puff%Bass0CATV_Claim6Sent' generated above has 94 bits of entropy, and is one of 10756 x 10 x 10756 x 10 x 10756 x 10 x 10756 x 10 x 10756. That's one password out of 1.4396*10^24. At 100 guesses per second, that's 456 trillion years if I did the math right.
On a system at work, where I installed a larger dictionary, it's 42245 words!
## Type ↓ ↓ ↓, User stejon-admin in ~ on lnxv001 ## ls -Al /usr/share/dict/words ; sudo dnf whatprovides /usr/share/dict/linux.words lrwxrwxrwx 1 root root 11 2025-11-18+20:24:18 /usr/share/dict/words -> linux.words Last metadata expiration check: 0:02:23 ago on Mon 30 Mar 2026 09:10:52 AM EDT. words-3.0-39.el9.0.1.noarch : A dictionary of English words for the /usr/share/dict directory Repo : @System Matched from: Filename : /usr/share/dict/linux.words
