Generating a password

Now, you might be wondering what use random characters might have. A prime example is generating passwords. Long, random passwords are always good; they're resistant to brute-force attacks, cannot be guessed, and, if not reused, are very secure. And let's be honest, how cool is it to generate a random password using the entropy from your own Linux system?

Even better, we can use input redirection from /dev/urandom to accomplish this, together with the tr command. A simple script would look like this:

reader@ubuntu:~/scripts/chapter_12$ vim password-generator.sh 
reader@ubuntu:~/scripts/chapter_12$ cat password-generator.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-11-06
# Description: Generate a password.
# Usage: ./password-generator.sh <length>
#####################################

# Check for the current number of arguments.
if [[ $# -ne 1 ]]; then
echo "Wrong number of arguments!"
echo "Usage: $0 <length>"
exit 1
fi

# Verify the length argument.
if [[ ! $1 =~ ^[[:digit:]]+$ ]]; then
echo "Please enter a length (number)."
exit 1
fi

password_length=$1

# tr grabs readable characters from input, deletes the rest.
# Input for tr comes from /dev/urandom, via input redirection.
# echo makes sure a newline is printed.
tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c ${password_length}
echo

The header and input checks, even the one with the regular expression checking for a digit, should be clear by now.

Next, we use the tr command with redirected input from /dev/urandom to grab readable characters in our set of a-z, A-Z, and 0-9. These are piped to head (more on pipes later in this chapter), which causes the first x characters for be printed to the user (as specified in the argument to the script).

To make sure the Terminal formatting is correct, we throw in a quick echo without an argument; this just prints a newline. And just like this, we've built our own private, secure, and offline password generator. Using input redirection, even!