Skip to main content

Command-line password generator for Linux

Linux has its own cryptographic generator which can easily be harnessed by the common user to generate extremely strong passwords. This password generator can be found at /dev/random. /dev/random generates pseudorandom numbers based on the available entropy of the system (see wiki page). A derivate of /dev/random called /dev/urandom does the same thing but it is more accessible while being slightly (theoretically) less secure. So what stops us from grabbing outout from /dev/urandom using cat? An output of the content of /dev/urandom will demonstrate that it is practically gibberish with very few usable random characters. The output of

cat /dev/urandom 

should convince the user.  However, it is possible to trim out the unwanted characters and only keep alphabets, numbers, and special characters with a simple filtering by the tr command.

cat /dev/urandom | head -c 10 | tr -dc "A-Za-z0-9_!"

This command will produce the desired output but it will generate very small passwords, which are truly random but which do not meet the length criteria in most cases. Therefore, this procedure needs to be repeated a large number of times until the required length of random passwords can be generated. It is better to write a bash script which will automate this procedure.

The following bash script generates random passwords and allows the user to control the length and number of random passwords that are generated. It also allows special characters to be included or excluded with a switch (argument). Since I am always in a hurry and don't like passing too many arguments, I wrote the script so that it can accept arguments in a shorthand manner in addition to the longhand manner (Unix style) of passing arguments. Shorthand way: ./ 10 2 1 will generate 2 random passwords of length 10 and they will all include special characters.

$ ./ 10 2 1


Or I could use the longhand (Unix-style) way of passing the arguments: ./ -l 10 -n 2 -s 1

$ ./ -l 10 -n 2 -s 1


The result will be the same. I have included the full code below which is well commented. I also provide explanation and cite sources below the code.


# generate random passwords using urandom CSPRNG.  

# v5.2 by Jones

Usage: ./ [options ...]
  -l password length. DEFAULT=16
  -n number of passwords to generate. DEFAULT=4
  -s special characters. DEFAULT=1. Set to 0 to disable selecting _!%
  -h help
Example 1: ./ -l 8 -n 2 -s 0

./ [password length] [number of passwords to generate] [include special characters] 

Example 2: ./ 8 2 0   "

if [[ "$1" =~ ^[0-9]+$ ]]; then  

 # Second and third argument might be empty which means $num and $special
 # will be empty at this point too. Set the values of $num and $special 
 #to the default values in case they are empty
 [ "$2" == "" ] && num=4
 [ "$3" == "" ] && special=1
 # If user uses arguments then use getopts.
 while getopts l:n:s:h option
  case "${option}"
          l) length=${OPTARG};;
          n) num=${OPTARG};;
          s) special=${OPTARG};;
          h) echo "$usage" ;;


# check if the first argument is an integer. If it is not then throw error. 
#=~ matches REGEXP ^[0-9]+$ which is one or more occurences of the numbers 0-9
if [[ !("$length" =~ ^[0-9]+$ )]]; then
 echo "Enter numbers only for the password length"
 echo "$usage"

# check if the second argument is an integer. If it is not then throw error.
if [[ !("$num" =~ ^[0-9]+$) ]]; then
 echo "Enter numbers only for the number of passwords to generate"
 echo "$usage"

# check if the third argument is an integer. If it is not then throw error. 
if [[ !("$special" =~ ^[0-1]+$) ]]; then
 echo "Enter only 0 or 1 for the third argument."
 echo "$usage"

if [[ $special == "1" ]]; then # if special chars needed: DEFAULT
# echo "first loop for 1"
 while [ $i -lt $num ] 
 # Keep looping till next password, which satisfies the required criteria, 
 # is successfully generated. May require many more passess for stricter 
 # requirements, usually smaller length passwords.
 pass=`tr -dc "A-Za-z0-9_!%" < /dev/urandom | head -c ${length} | xargs`

 if [ `echo $pass | grep "%" | grep "[0-9]" ` ]; then
   echo $pass
else  # if special chars are NOT needed
# echo "second loop for 0"
 while [ $i -lt $num ]
 pass=`tr -dc "A-Za-z0-9" < /dev/urandom | head -c ${length} | xargs`

 if [ `echo $pass | grep "[0-9]" ` ]; then
   echo $pass


Parsing the command-line

The block of code which parses the command-line options using getopts is found at lifewire. The post at that link provides a clear explanation of what the block of code while getopts l:n:s:h option does. So I will only mention that the while loop parses through the command-line arguments and if it finds any matches to the options that the script expects, then it assigns the value passed to the option to the corresponding variables, defined in the script.

Checking validity of arguments passed

Since the script can only accept numeric arguments, their values need to be checked for non-numeric entries. If found an error message is displayed. To check if the values are numeric we can treat the value as a string and verify that every character lies between 0-9. This ensures that there are no non-numeric characters in that string which in turn implies that the string is a number. "$num" =~ ^[0-9]+$  does exactly that. =~ operator is used for REGEX matching of lvalue $num to rvalue ^[0-9]+$ (which is a REGEX that matches every character to characters between 0-9). A similar test is applied for the special variable which acts as a switch to include or exclude special characters. However, it only takes values 0 or 1. Hence its REGEX is ^0-1+$. For more information on regular expressions see this quick reference.


germacran said…
Hello Jones,

I noticed that you used getopts to parse options passed.
Unfortunately, getopt doesn't parse options longer than one character.

I wrote about alternative options on my website. If you would like to send you the link to add it as an additional resource, it would be my pleasure.



Popular posts from this blog

Fastest way to send multiple drafts from gmail

People claim that the fastest way to send multiple email drafts is to use Gmail IMAP with email client like Outlook or Evolution or Thunderbird. But I have found this is not true. Because Thunderbird and Evolution etc. email clients treats the drafts as emails still to be edited. So it is not just simple select all and hit send. Each email draft has to be opened and sent separately. That is a lot of clicks and mouse movements, wasting precious time and energy. I have a better solution which involves minimum keystrokes and mouse usage. Efficiency booster technique for sending emails.
If someone is feeling adventurous and want to try it from the Gmail interface itself, here's how to do it in the fastest possible manner. It involves using the mouse once. Select the first draft. Gmail would open a new email box and put the cursor inside the box to write.Press TAB once to go the Send button.Press ENTER to send. Now Gmail sends it and the box is gone but the highlight goes to the last li…




Pratham college-er din ta
Aajo thik e mone poRey scene ta
Dada didi haath dhorey siNRi tei bose poRey
Aamar chokh ta ghorey bon bon bon bon

Sweetheart, I am seating alone
Sweetheart, for me there is none

DhoNk gile chole gelo pratham maas
Meye dekhlei feli deergho-shwash
DhoNk gile chole gelo pratham maas
Meye dekhlei othe nabhishwash
Meyera bheeshan smart poRey chhoto mini-skirt
Aamar e je sheet korey kon kon kon kon

Sweetheart, I am seating alone
Sweetheart, for me there is none

Taarporey kete gelo maas chaar
Fuse holo je kato future
Bandhura purse khule eke oke taake tole
Aamar pran ta korey chon mon chon mon

Sweetheart, I am seating alone
Sweetheart, for me there is none

Ekdin lawn theke beriye
Ek tanayaar dike taakiye
Hawt korey ki je holo magaj ta ghurey gelo
Taar kaaner saamne kori ghyan ghyan ghyan ghyan

Sweetheart, I am seating alone
Sweetheart, for me there is none

Taarpore cla…

How to join audio tracks smoothly in Audacity

Audio tracks can be mixed easily in full fledged video editors like kdenlive or Adobe Premiere but for mixing or joining audio they would not provide the amount of control that audio editors like Audacity provide. The example I am going to show today would demonstrate the range of tools in Audacity that allows us to control the waveform and to mold it to our desire.

Today I am going to take a small track like a small 1 min. clip of storm sound and make a long continuous sounding storm audio clip from it.

STEP 1 : Open file
Open the clip in Audacity.

STEP 2 : Removing unwanted audio portion
There is always unwanted sections of the audio that we have to discard. Select the portion of background noise or unwanted audio.

Press DELETE key.

STEP 3 : Duplicating the track
Now we make a copy of the entire waveform and paste it at the end of the track.

Select the SELECT tool (the one which looks like I). Then select the whole waveform and prss Ctrl+c. Now click approximately at the end of the…