Skip to content
Advertisement

Linux tr command not working as expected

I have this password generator:

pass () {
    # Generates a random password
    local size="${1:-12}"
    local alphabet="$2"
    </dev/urandom tr -dc "$alphabet" | head -c$size ; echo ""
}

Which works fine as follows:

» pass 20 '[:alnum:]'
DpEf8bMp7zfkvSoudItS

But fails as follows:

» pass 20 '[:alnum:]@#%+-/~'
JSNweE,.EU+P.l5nqkzd

The tr command is explicitly saying:

remove all characters which do not belong to the given set

Thus the characters , and . are unexpected.

Where do they come from?

Advertisement

Answer

There’s also another part of tr‘s man page that you overlooked:

CHAR1-CHAR2

all characters from CHAR1 to CHAR2 in ascending order

So the part +-/ will mean the characters +, ,, -, . and /. (man ascii is useful here).

For a hyphen you can escape it:

pass 20 '[:alnum:]@#%+-/~'

use 55 instead:

pass 20 '[:alnum:]@#%+55/~'

or put it at the end:

pass 20 '[:alnum:]@#%+/~-'
Advertisement