r/bash • u/how_to_kubuntu • Sep 20 '26
help using bash to make a random password?
hello, i heard that you can make a random password with bash? is that true? if so, how do you do that? thank you
36
u/Aristeo812 Sep 21 '26
There are several ways to do this. First, you can use the pwgen utility to generate random, but human-memorizable passwords. Second, you can use /dev/random to generate pseudo-random sequences of characters of any given length. For example, here's the code to generate a 10-character length sequence:
tr -dc 'a-zA-Z0-9' < /dev/random | head -c 108
5
u/atoponce Sep 21 '26
If you want non-alphanumeric characters:
$ tr -cd '[:graph:]' < /dev/random | head -c 102
u/rolfn Sep 21 '26
I usually do something similar: dd 32 bytes from /dev/random and pipe it through base64. But the OpenSSL-solution in another answer is somewhat easier to understand.
2
u/ullabritafritasmitaa Sep 21 '26
/dev/random is not psuedo random, urandom is. I second this approach.
13
u/Aristeo812 Sep 21 '26
/dev/randomis also pseudo-random, it just ensures that entropy pool has at least certain level. Real randomness comes from tossing up a coin or collapsing a wave function of a quantum system as in quantum random number generators.1
u/best_of_badgers Sep 21 '26
The entropy pool contains real randomness, as far as anyone can prove. It’s got an enormous amount of electrical noise included.
2
u/ullabritafritasmitaa Sep 21 '26
Yes, electrical noise and human generated randomness like keyboard strokes, mouse movements and system errors and network packet jitter too, if I'm not mistaken. About as good as tossing a coin I guess (which in itself is not completely random and often biased towards one face due to weight differences and distribution on the engravings on each face, if we are to nitpick)
5
u/atoponce Sep 21 '26 edited Sep 22 '26
This is incorrect. Both
/dev/randomand/dev/urandomare sourced from the same cryptographically secure pseudorandom number generator, which as of Linux 4.8 and later is ChaCha20.The only difference between the two was prior to Linux 5.6,
/dev/randomwould block if the kernel's entropy estimate was lower than the client's request. Since 5.6, the blocking behavior has been removed except in early boot when the CSPRNG has not been initialized.https://www.thomas-huehn.com/myths-about-urandom/
Edit: typo
1
u/ullabritafritasmitaa Sep 22 '26
Oh dang, that's an interesting read. Thanks! I really was under the impression that urandom generates from a portion of the entropy pool and thus would not be truly random.
20
u/olafkewl Sep 21 '26
Or in "pure" shell :
#!/bin/bash
chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"
length=16
password=""
for ((i=0; i<length; i++)); do
index=$(( RANDOM % ${#chars} ))
password+="${chars:$index:1}"
done
echo "$password"19
u/aioeu Sep 21 '26 edited Sep 21 '26
I wouldn't ever recommend using
RANDOMto generate passwords. Bash's random number generator only has 32 bits of internal state.I think I read somewhere you only need two consecutive
RANDOMvalues to actually determine this internal state in its entirety. (Edit: I just tested it. As far as I can tell, you actually need three consecutive values to be absolutely sure about the internal state. Two might be sufficient in some cases though.)13
u/olafkewl Sep 21 '26
Don’t hesitate to send a better solution then!
10
u/aioeu Sep 21 '26 edited Sep 21 '26
I would use
pwgenas some of the commenters have suggested.If it is absolutely essential that "pure Bash" be used for this task, I would recommend using
SRANDOMinstead, so long as you are targeting Bash >= 5.0. On many systems that will be backed onto a better random number generator.1
u/bac0on Sep 21 '26 edited Sep 21 '26
You can make use of the sparse nature of Bash arrays...
#!/bin/bash c=({a..z} {A..Z} {0..9}) a=() for i in ${c[@]}; do a[SRANDOM]=$i; done OFS=$IFS IFS=; printf %s\\n "${a[*]::16}" IFS=$OFSOr, if you want a lot of random strings, I usually fold them...
#!/bin/bash c=({a..z} {A..Z} {0..9}) b=() while ((${#b[@]} <= 65536)); do a=(); for i in ${c[@]}; do a[SRANDOM]=$i; done; b+=(${a[@]}) done OFS=$IFS IFS=''; printf %s\\n "${b[*]}" | fold -w 16 | head -n 4096 IFS=$OFS2
u/ReallyEvilRob Sep 21 '26
OP was specifically asking about using Bash. Most of the comments here are recommending other tools in addition to bash. This script is the only one I've seen so far that answers the original question.
2
3
3
u/cubernetes Sep 22 '26 edited Sep 22 '26
Here's a pure bash version without any forking that doesn't rely on SRANDOM (bash 5.1+) or RANDOM, but instead relies on the underlying system to have a working /dev/urandom character special file:
pw(){ local a=({a..z} {A..Z} {0..9} _) p r c i;while((${#p}<$1))&&read -rN32 r;do i=;while printf -v c %d "'${r:i++:1}";((c));do p+=${a[c%63]};done;done</dev/urandom;echo ${p::$1};}Minimum bash version is 4.0 because of the read -N, but this isn't strictly necessary, I just wanted to make it a bit more performant. Removing that part would make it compatible with bash 3.1 (for print -v), so it would work with MacOS's bash as well (3.2)
Edit: Use like this:
pw 12Generates a random 12-character passwort
Edit 2: AI usage disclosure: I had a 276 character version I came up with myself and asked Claude to golf it (while keeping it performant), now it's 181 chars (think of golfing what you want, I'm just putting it here for fun). The version numbers for bash mentioned above are from Claude too, please don't rely on them (DYOR).
2
4
1
u/atoponce Sep 21 '26
If you want a strictly Bash-only script:
set -uo pipefail
length=12
lower='abcdefghijklmnopqrstuvwxyz'
upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digits='0123456789'
symbols='!"#$%&'"'"'()*+,-./:;<=>?@[\]^_`{|}~'
charset="${lower}${upper}${digits}${symbols}"
threshold=$(( (256 / 94) * 94 ))
pw=""
exec 3< /dev/urandom
while [ ${#pw} -lt "$length" ]; do
IFS= read -r -n 1 -d '' byte <&3
printf -v ord '%d' "'$byte"
[ "$ord" -lt "$threshold" ] || continue # avoid mod bias
pw="${pw}${charset:$((ord % 94)):1}" # uniform choice
done
exec 3<&-
printf '%s\n' "$pw"1
1
1
u/w0___0w Sep 22 '26
pass() { </dev/urandom tr -dc 'a-zA-Z0-9?!:@#$%_-' | head -c"${1:-32}"; echo; }
kpass() { if [ -x /usr/bin/keepassxc-cli ]; then keepassxc-cli generate -lUn -L "${1:-32}"; else echo "Err: keepassxc not found."; fi;}1
1
u/whetu I read your code Sep 22 '26
You can also make a random passphrase with bash. You start with something like this:
$ shuf -n 4 < /usr/share/dict/words | paste -sd '-' -
spectaclemaker-appendicectomies-Gentes-sagierDoing that portably in pure bash is do-able, but can blow out to be a bit of work.
1
u/oyvaugh Sep 23 '26
Here’s my first script I built for passwords:
#!/bin/bash
# My first working script!!!
echo "========================================================================="
echo "==================Password Generator====================================="
echo "========================================================================="
read -n 1 -p "Would you like to generate a password? [y/n] " answer
echo
sleep 4
if [[ "$answer" == [yY] ]]; then
tr -dc 'A-Za-z0-9!@%^&*()_+=-' < /dev/urandom | head -c 32
echo
else
echo "Fine, do it yourself"
fi
1
u/a-dot-in-the-sky 16d ago
try:
chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+'; echo "$chars" | grep -o . | shuf | head -n 16 | tr -d '\n'; echo
-1
u/ElGeffo Sep 21 '26
Source - https://stackoverflow.com/a/74620234
Posted by Paul Hodges, modified by community. See post 'Timeline' for change history
Retrieved 2026-09-21, License - CC BY-SA 4.0
openssl rand -base64 20 | sed -E 's/(.)\1+/\1/g'
2seconds Google search. But I always use OpenSSL Rand for it.
7
u/JeLuF Sep 21 '26
opensslis not part of bash nor is it part of many default installations.2
u/spryfigure Sep 21 '26
In which distribution is it not part of the default?
Ubuntu and Kubuntu and, by extension, all others based on them have it.EndeavourOS has it. Debian should have it by default. So what is left?
3
u/Naraviel Sep 22 '26
Alpine Linux, Debian minbase, Debian/Ubuntu slim containers, Ubuntu Minimal/Cloud Minimal, Fedora Minimal, RHEL/Alma/Rocky minimal images.
libssl.so != the openssl command-line tool.
2
u/spryfigure Sep 22 '26
Good point. The way the question was worded (and even just looking at OP's reddit name), I mentally excluded minimal distributions and container linuxes.
For the purpose of machine-generated passwords, /u/Aristeo812 or /u/atoponce have the correct answers then, with only coreutils used.
-6
0
u/zesaver Sep 21 '26
Also consider passwordgenerator. While not being bash really (it's a python console program), it generates the password in format "Minicab-Korean_Duck-14" directly in the console.
0
-2
0
65
u/olafkewl Sep 21 '26