Tested on OpenBSD 6.3

Generate random string with random(4)

The urandom device produces high quality pseudo-random output data.

“Never use /dev/random. On OpenBSD, it does the same as /dev/urandom, but on many other systems, it misbehaves. For example, it may block, directly return entropy instead of using a stream cipher, or only return data from hardware random generators."

Limit character set

Keep characters you need and exclude everything else tr(1). For example, keep characters from 1 to 6.

$ tr -cd '1-6' < /dev/urandom


fold(1) into twenty-character wide lines, then head(1) the first line:

$ tr -cd '1-6' < /dev/urandom |
fold -w 20 |
head -n 1

Another way to take first 20 characters, use dd(1):

$ tr -cd '1-6' < /dev/urandom |
echo $(dd count=20 bs=1 status=none)

Adjust character set

Use any range of characters. For, example from the first printable char, space, to tilde.

$ tr -cd ' -~' < /dev/urandom |
fold -w 20 | head -n 1
a(k#$(K ?I?d!^NM^(5x

Or all alphanumeric characters, comma, and dot.

$ tr -cd '[:alnum:],.' < /dev/urandom |
fold -w 20 | head -n 1

Or just use jot(1)

Run jot(1) with the option -r to print random numbers.

$ jot -r 3

Set the range from 32 to 126 (ASCII codes of space and tilde), print a character represented by this number (-c), and separate characters with an empty string (-s '').

$ jot -rcs '' 20 32 126

Or use openssl(1)

openssl(1) with rand command outputs pseudo-random bytes and with the -base64 option it encodes the output to its printable form.

$ openssl rand -base64 20

“I’d be wary of using openssl(1)→Base64 unless you know that “=” can only come at the end because it’s used as padding and so it’s not adding anything extra to the password’s entropy."
Tim Chase (@gumnos)

See also

diceware, pass

Thanks to David Dahlberg, Tim Chase, Bojan Nastic, horia, Ben Bai for the hints, and to Theo de Raadt for arc4random.