Passing Variable with Special Characters as Password Breaks Bash Script. How to Sanitize Special Characters in Bash

How to pass variables with special characters into a bash script when called from terminal

Sanitization is absolutely not needed.

The simplest solution, assuming your script is properly executable (has +x permissions and a valid shebang line), is:

./updatelog.sh "$filesize" "$filename"

If for some reason you must use the bash -c, use single quotes instead of double quotes surrounding your code, and keep your data out-of-band from that code:

bash -c 'updatelog.sh "$@"' 'updatelog' "$filesize" "$filename"

Note that only updatelog.sh "$@" is inside the -c argument and parsed as code, and that this string is in single quotes, passed through without any changes whatsoever.

Following it are your arguments $0, $1 and $2; $0 is used when printing error messages, while $1 and $2 go into the list of arguments -- aka $@ -- passed through to updatelog.sh.

Simple solution for handling special characters in shell script input

Hm.. Double quotes are not enough. Must use single quotes, because the rare situation, for example

mycommand --password "AAA$PWD" #is worng for any exported environment varname
mycommand --password 'AAA$PWD' #ok

Here is no way avoid this, because your users using a sort of shell, what have variable expansions and metachar-globbing. Your command getting already expanded args, so here is no way catch this in your script.

The only way - as @Bohemian told above - reading the password from a tty. You can write a simple wrapper around your current script, what will read the password from a tty and after will execute your script with properly escaped --pasword argument.

Using a variable as another variable in a bash script?

If you REALLY want to be able to display the special characters, you can use zenity --text-info as shown below. It's not as aesthetically pleasing, but it can be done.

Just another 2¢

echo "Here is your random $newnumber character password, you can copy and paste it wherever you wish...

$PASS

The passwords generated by this application are very strong, here are the numbers;

Length: $newnumber characters
Character Combinations: 96
Calculations Per Second: 4 billion
Possible Combinations: 2 vigintillion

Based on an average Desktop PC making about 4 Billion calculations per second

It would take about 21 quattuordecillion years to crack your password.

As a number that's 21,454,815,022,336,020,000,000,000,000,000,000,000,000,000,000 years!" | zenity --text-info --title "Your $newnumber character password" --width 600 --height 500`

Addendum,

After playing with it some more, it appears that zenity doesn't like printing variables with special characters.

This script should work

I made 2 changes.

1 newnumber=`zenity.... This will read the input from zenity.

2 Removed some special characters from the MATRIX

I marked all changes with #CHANGED

Here's the revised script.

#!/bin/bash
# May need to be invoked with #!/bin/bash2 on older machines.
#
#Random 32 character password generator
#
zenity --info --title="32 Character Password Generator" --text="Hi, so you want to get yourself a new password? You've the perfect little application here, just click OK to generate your new password."

number=32
# CHANGED
newnumber=`zenity --entry --text="Please enter a number (no limitations!) :" --entry-text="$number"`
# read newnumber
[ -n "$newnumber" ] && number=$newnumber
#CHANGED Removed offending special characters
MATRIX="0123456789?_+-!$%^>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
# Password will consist of standard characters.
LENGTH="$newnumber"
#This variable can be changed for password lenth
#(need to try get zenity to let user choose that number)

while [ "${n:=1}" -le "$LENGTH" ]
# := is "default substitution" operator.
# So, if 'n' has not been initialized, set it to 1.
do
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
# Very clever, but tricky.

# Starting from the innermost nesting...
# ${#MATRIX} returns length of array MATRIX.

# $RANDOM%${#MATRIX} returns random number between 1
# and [length of MATRIX] - 1.

# ${MATRIX:$(($RANDOM%${#MATRIX})):1}
# returns expansion of MATRIX at random position, by length 1.
# See {var:pos:len} parameter substitution in Chapter 9.
# and the associated examples.

# PASS=... simply pastes this result onto previous PASS (concatenation).

# to let zenity show the password being built one character at a time, uncomment the following line
# zenity --info --text="$PASS"
let n+=1
# Increment 'n' for next pass.
done
# CHANGED $PASS to '$PASS' below
zenity --info --title="Your 32 character password" --text="Here is your random 32 character password, you can copy and paste it wherever you wish...

$PASS

The passwords generated by this application are very strong, here are the numbers;

Length: 32 characters
Character Combinations: 96
Calculations Per Second: 4 billion
Possible Combinations: 2 vigintillion

Based on an average Desktop PC making about 4 Billion calculations per second

It would take about 21 quattuordecillion years to crack your password.

As a number that's 21,454,815,022,336,020,000,000,000,000,000,000,000,000,000,000 years!" # you could redirect to a file, to store the password. Use something like $PASS 2> /file/name

exit 0

Escaping characters in bash (for JSON)

OK, found out what to do. Bash supports this natively as expected, though as always, the syntax isn't really very guessable!

Essentially ${string//substring/replacement} returns what you'd image, so you can use

MSG=${MSG//\'/\\\'}

To do this. The next problem is that the first regex doesn't work anymore, but that can be replaced with

git log -n 1 --pretty=format:'%s'

In the end, I didn't even need to escape them. Instead, I just swapped all the ' in the JSON to \". Well, you learn something every day.



Related Topics



Leave a reply



Submit