I got a strange behavior when running a script with arguments that contains a command substitution. I would like to understand why is this behavior happening. The script is:
#!/bin/bash
# MAIL=$1
# USER=$2
PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-20} | head -n 1);
echo "$PASSWORD"
Then I run: ./test.sh mail user
, I get the error:
fold: invalid number of columns: ‘mail’
and the Password is not generated.
If I don't pass an argument or I don't generate the password, it works fine.
I think I've found out what is happening:
When running a script with two arguments the $1 and $2
have the passed values. Example:
./test.sh arg1 arg2
have $1 -> arg1
and $2 -> arg2
When using a pipe inside a script, the original arguments are still passed and thus if you have two arguments as input you will have the piped output inserted into the third place $3
.
$1 -> arg1
$2 -> arg2
$3 -> piped output
So a working solution would be:PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${3:-20} | head -n 1);
but if you vary the input arguments, it will not work. Therefore the best solution is what @KamilCuk suggested:
PASSWORD=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1);
If you do not wish to pass the first script argument to fold
, then do not use $1
in it.
PASSWORD=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1);
# ^^ - pass the number, not $1
echo "$PASSWORD"