Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
shell/bash generate random alphanumeric string
# bash generate random alphanumeric string
# bash generate random 32 character alphanumeric string (upper and lowercase) and
NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
# bash generate random 32 character alphanumeric string (lowercase only)
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
# Random numbers in a range, more randomly distributed than $RANDOM which is not
# very random in terms of distribution of numbers.
# bash generate random number between 0 and 9
cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | head --bytes 1
# bash generate random number between 0 and 99
NUMBER=$(cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | sed -e 's/^0*//' | head --bytes 2)
if [ "$NUMBER" == "" ]; then
# bash generate random number between 0 and 999
NUMBER=$(cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | sed -e 's/^0*//' | head --bytes 3)
if [ "$NUMBER" == "" ]; then

Thanks :)

ilikenwf commented Jan 9, 2014

If you need lowercase, tack another pipe and tr '[:upper:]' '[:lower:]' there.


Didn't google recently suffered downtime due to the lack of entropy ? Does reading from /dev/urandom ever block ?

@javouhey There are many different problems with entropy, but in regards to using /dev/urandom, it is the preferred method in such an example.

/dev/random seeds /dev/urandom, which is then expanded allowing smaller amounts of entropy to result in larger sets of 'random' data. It is definitely recommended to use /dev/urandom and not /dev/random.

@earthgecko Thank you for this script!

Could you help me with an issue I have? When I run it it works like a charm, but when I put it in another script it hangs.

Specifically I am running it a Composer post-install hook to generate a random salt. I suppose it starts a new child process for the command.

In the Activity Monitor I could see the process is reaching nearly 100% CPU usage.

My problem is most probably caused by: symfony/symfony#9409

cat /dev/urandom outputs a large amount of data which fails when the Symfony\Process library starts it as a child process.


ghost commented Feb 22, 2014

Thanks for your script!

I put this into my .bashrc

    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1

Use it like this:

$ random-string

$  random-string 16

This doesn't work on a Mac:

$ cat /dev/urandom | tr -dc 'a-zA-Z0-9'
tr: Illegal byte sequence

Nor on FreeBSD 9.2:

$ cat /dev/urandom | tr -dc 'a-zA-Z0-9'
tr: Illegal byte sequence


ghost commented Apr 29, 2014

Try this: LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | fold -w ${1:-32} | head -n 1+}.

This works on the CLI, but how is this used in the above script? I'm still getting errors within a shell script.

Is there any advantage to using fold + head over just head?

NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32);

mihigh commented Jun 22, 2014

@dlangille for mac use:
cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1

wavic commented Jun 29, 2014

What about these symbols



dmp1ce commented Dec 1, 2014



NEW_UUID_MORE_CHARACTERS=$(cat /dev/urandom | tr -dc "a-zA-Z0-9!@#$%^&*()_+?><~\`;'" | fold -w 32 | head -n 1)

thanks, works like a charm on the mac! :)

what if i want my string of any particular length only let's just say , in this case , I want it of 10 characters long only ?

@shahaksay94 fold it to 10 instead of 32

Nice. Thanks!

# Without visual similar chars: IOl01
tr -dc 'A-HJ-NP-Za-km-z2-9' < /dev/urandom | dd bs=32 count=1 status=none

+1 @jmack for head -c instead of fold

axlm commented Feb 10, 2015

@dlangille, it works on FreeBSD if you are root.

expz commented Feb 20, 2015

fewer random bytes could be discarded:

base64 /dev/urandom | tr -d '/+' | dd bs=32 count=1 status=none

or to delete o, O, and 0, for example:

base64 /dev/urandom | tr -d '/+oO0' | dd bs=32 count=1 status=none

or as a function:

mkpasswd() { base64 /dev/urandom | tr -d "/+$2" | dd bs="$1" count=1 status=none | xargs echo; }

used like: mkpasswd 32 'oO0' or mkpasswd 32 '0-9'

👍 @expz

Instead of status=none you can also redirect stderr to /dev/null:

base64 /dev/urandom | tr -d '/+' | dd bs=32 count=1 2>/dev/null

Suggest, if I want Special character in the output of following command.

strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 8 | tr -d '\n'; echo;

for a full bunch of random chars:

tr -dc [:graph:] < /dev/urandom | head -c 32

expz commented Jul 6, 2015

If you're going to generate just one password, fine, there's a million ways. But if you're going to generate a million, do you really want to discard 90% of the random bits your computer generates? It seems to me that the passwords will come out as a different kind of 'random'. That's why I suggest a different solution.

on mac

○ → cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
tr: Illegal byte sequence


LC_ALL=C; cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1

jkwages commented Aug 1, 2015

Soooo....what if I wanted to create a file of generated passwords using this script. Say 1000 of them. I know how to generate multiples, but is it possible to save them to a text file for later use?

fnkr commented Aug 3, 2015

Why don't use head -c instead of fold? Benefits: performance, works on Git Bash under Windows too.

cat /dev/urandom | tr -dc 'a-z0-9' | head -c 32

LC_ALL=C; dd if=/dev/urandom bs=256 count=1 2> /dev/null | tr -dc 'a-zA-Z0-9' | head -c 32; echo

Instead of cating /dev/urandom, just read 256 bytes, which are enough to have a 32 char string.

denzuko commented Oct 1, 2015

would be nice if everyone would stop catting all over themselves as the < filename parameter does the same thing.

Here's an example that works on all POSIX systems even Sun unix and AIX and is always going to get 32 characters (ie a DWORD byte read 8 times):

   tr -dc '[:alnum:]' < /dev/urandom  | dd bs=4 count=8 2>/dev/null

denzuko commented Oct 1, 2015

@jkwages yes just append the >> my.password.lst_file to the command to pipe into a file or subshell.

What the >> part means is take stdout from the pipe line/command and append to the end of file named my.password.lst_file. Also, the > means overwrite the file with the latest output.


for idx in `seq 1 1000`; do
    tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >> password.lst

An async threaded version would look like this:

for idx in `seq 1 1000`; do
    (tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >>password.lst) & # thread number 1
    (tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >>password.lst) & # thread number 2

mckyj57 commented Nov 17, 2015

Perl one-liner in case you only want to have one dependency:

perl -e '@c=("A".."Z","a".."z",0..9);$p.=$c[rand(scalar @c)] for 1..32; print "$p\n"'

Probably not as random as it could be, but should be good enough for this purpose.


$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
tr: Illegal byte sequence

This is on ISX Yosemite though

I used the one-liner by @mckyj57, which works great. Thanks!

u2mejc commented Jan 29, 2016

IMHO here are some simpler options, pick the right tool for the job:

  • Inside bash scripts:
    • Random temporary files: mktemp
    • Random number: echo $RANDOM
  • Strings, length is players choice, these should be 32 bytes off the top of my head:
    • (lowercase alpha and numbers) openssl rand -hex 16
    • (all alpha, numbers and +/= chars): openssl rand -base64 24

ernestm commented Feb 17, 2016

cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1

works for me on El Capitan but it triggers "set -e" for some reason and will stop scripts with set -e going; I've run the pieces of this and don't see any nonzero exit codes and am not sure why, but FYI.
Same thing with

env LC_CTYPE=C tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=2 2>/dev/null

I'm just using $RANDOM now as a workaround but would like a slightly larger space...

swklzr commented Jun 6, 2016 edited

  1. 400+ out / 5 sec
    $(base64 /dev/urandom | tr -d '/+' | head -c 32 | tr '[:upper:]' '[:lower:]')
  2. 1000 out / 5 sec
    $(head -c 16 /dev/urandom | md5sum | head -c 32)

ARandomScientist commented Jun 9, 2016 edited

Made an interactive version.

#!/usr/bin/env bash

echo ""
echo "Welcome to the random alphanumeric sequence generator."
echo 'Random sequence generation taken from:'
echo ""

echo -n "Enter desired sequence length: "
read input_variable

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $input_variable | head -n 1

echo ""
echo "You're welcome."

I don't particularly care for how I used echo to separate text bodies. I feel as if there's a more elegant way to do that.

I'm actually pretty new to coding in general, so if you have any tips, please don't hesitate to give them.

apalii commented Jun 10, 2016 edited

"simple is better then complex"

PASSWORD=`pwgen -s 10 1`

man pwgen - for more details

These two commands generate random passwords and passphrases, respectively. You can use the first command with the right configuration file to generate random alphanumeric strings.

shuf --random-source=/dev/urandom --repeat --head-count=20 file_with_characters | tr --delete '\n'

shuf --random-source=/dev/urandom --repeat --head-count=7 file_with_words | tr '\n' ' '

The password generator requires a file_with_characters containing all the characters you want the password to use, one character per line, and exactly one time each. The file must not contain blank lines, and lines must be newline-terminated.

The passphrase generator requires a file_with_words containing all the words you want the passphrase to use, one word per line, and exactly one time each. The file must not contain blank lines, and lines must be newline-terminated.

The --head-count option specifies the length of the password--in characters--or passphrase--in words.

0x04C2 commented Sep 15, 2016

Very very useful script!!!

But I have still question here:
I usually add the set -euo pipefail in the beginning of shell script. If I use cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c ${len} in the script, bash will raise the pipe error and exit 141. The head retrieves enough the bytes and send SIGPIPE to tr.

Is there any solution to handle this?


earthgecko commented Sep 15, 2016

@fufuwei try not using pipes .e.g.

head -c 256 /dev/urandom > /tmp/urandom.out
tr -dc 'a-zA-Z0-9' < /tmp/urandom.out > /tmp/
head -c ${len} /tmp/

0x04C2 commented Sep 16, 2016

@earthgecko cool! Thanks

My latest incarnation:

head -c24 < <(tr -dc '\041-\176' < /dev/urandom)

Generates a 24-char string consisting of any printable ASCII character from ! to ~.
Change 24 to whatever length you require, obviously.

Slight update to prevent password containing single quotes, making it easier to quote a variable containing the password.

head -c24 < <(tr --delete --complement '\041-\046\048-\176' < /dev/urandom))

This is what I ended up using in bash on OS X to have filename-safe string
cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | fold -w 4 | head -n 1
If you need 16 chars then use
cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1

You get the idea

sora8964 commented Jan 8, 2017


@fhfuwei re: pipefail setting, you can coax it to continue as so;

set -eo pipefail
random="$(LC_CTYPE=C tr -dc 'a-zA-Z0-9-_' < /dev/urandom | head -c12)" || true

without || true at end, it will exit script.

Thanks! 👍

Fantastic work, thanks for sharing!

jmalki commented Feb 9, 2017

Strange that this command after 100 iternations only produces a + symbol. What did I do wrong?

cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9!@#$%^&*()_+?><~\;' | fold -w 16 | head -n 1`

Good job! That's what I need!

fjarrett commented May 4, 2017

To generate WordPress security keys and salts for a wp-config.php file:

# 64 random printable characters
# Excludes: space, double quote, single quote, and backslash
echo $(cat /dev/urandom | tr -dc [:print:] | tr -d '[:space:]\042\047\134' | fold -w 64 | head -n 1)
# jVig,+1&z3]}DT*$pvXPY#!z!^A-;[c0n!c*Ju=fy9`+yOauYAve<#fL]?>B9U;/

This will yield results similar to the official generator:


How de generate code like this "YH7EF",
with only one time number (nevemind where) or not and letter must differents


pascalandy commented May 29, 2017 edited

Within a Docker container


docker run --rm alpine sh -c \
"cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $LENGTH | head -n 1";

Szero commented Jun 4, 2017 edited


#!/usr/bin/env bash

string=$(tr -dc '[:upper:]' < /dev/urandom | fold -w 5 | head -n 1)
if ((RANDOM % 2)); then
    sed "s/./$((RANDOM % 10))/$((RANDOM % 5 + 1))" <<< "$string"
    echo "$string"

This will generate string with length of 5 characters, sometimes with one number in it sometimes without.

My question is, how to allow -= those symbols..

I got it, how to do this

manvedu commented Jun 15, 2017


dpwolfe commented Jul 5, 2017

For the simple macOS solution (currently Sierra 10.12.5), ShellCheck gives a SC2002 warning about a useless cat. I made a small modification to avoid that:

env LC_CTYPE=C tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1

Thank you @mihigh!

edlugh commented Jul 6, 2017

How can I create a random password with specific format.

  1. Length 12
  2. Especial caracheres 2 or 3
  3. Number 2 or 3
  4. Lower 3+
  5. Upper 3+

Great, taking all the above:

env LC_CTYPE=C tr -dc 'a-z0-9' < /dev/urandom | head -c24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment