Get and use a password with special characters in Bash shell
I see two potential problems with how you're reading and using the password:
- When you use the
read
command without the-r
option, it'll try to interpret escape (backslash) sequences, which may cause trouble. - When you use a variable without wrapping it in double-quotes, it'll try to split the value into separate words and also try to expand any wildcards into a list of matching filenames. This can cause massive confusion, so you should almost always double-quote variable references.
Fixing these potential problems gives this script snippet:
read -rs -p "Password : " bindDNPass
ldapadd -H ldap://localhost -x -w "$bindDNPass" -D "dn=cn=Admin" -f /tmp/file.ldif
...But, while you should do both of these mods to make your script more robust, neither of these will change how it handles the password $Something18$
. In fact, when I tried your original snippet with that password, it got passed to ldapadd
correctly. If your actual password has some other special characters in it (or you've played with the value of IFS
), these might help; otherwise, there's something else going on.
If your password still doesn't work after these fixes, try putting set -x
before the ldapadd
command (and set +x
after) so it'll print what's actually being passed to ldapadd
. Well, it'll print it in a possibly confusing form: it'll print an equivalent command to what's actually being executed, which means it'll add quotes and/or escapes to the password parameter as necessary so that you could run that command and it'll do the same thing. When I tried it with $Something18$
, it printed:
+ ldapadd -H ldap://localhost -x -w '$Something18$' -D dn=cn=Admin -f /tmp/file.ldif
...where the single-quotes mean that what's inside them is passed directly, with no parsing. It could also have printed any of the following equivalent commands:
+ ldapadd -H ldap://localhost -x -w \$Something18\$ -D dn=cn=Admin -f /tmp/file.ldif
+ ldapadd -H ldap://localhost -x -w "\$Something18\$" -D dn=cn=Admin -f /tmp/file.ldif
+ ldapadd -H ldap://localhost -x -w $'$Something18$' -D dn=cn=Admin -f /tmp/file.ldif
so you have to take what it prints, and figure out how that'd be parsed by bash, in order to figure out what's actually being passed to ldapadd
. But at least it'll give you some information about what's actually happening.
Oh, and you may notice that the DN argument isn't being double-quoted. That's because it doesn't contain any special characters, so the double-quotes aren't doing anything, so it just left them off.
curl request for login with password having special character in bash script?
- You should always quote variable expansions
- Use single-quotes to disable variable expansions and other special characters
Some issues with your current code:
echo $line
is not properly quoted, and will break on whitespace and other special characters; useecho "$line"
- As @GordonDavisson suggested in the comments,
printf '%s\n' "$line"
would actually be safer thanecho
, which may not work correctly depending on the contents of$line
- As @GordonDavisson suggested in the comments,
admin:'$pass'
will resolve to the literal charactersadmin:$pass
being passed tocurl
; use"admin:${pass}"
https://$ip:443/admin
is also not properly quoted, use"https://${ip}:443/admin"
- If
$line
is being set with a literal password in the script you'll want single-quotes to have the shell ignore special characters;line='...,sbxy$sT_i7d6I*7'
pass special characters from input to bash script
The problem is probably not in your script at all, but rather on how you call it. At least from the snippets you provide, it doesn't seem like the password field is being evaluated.
So, when you call the script, if an argument contains something like $a, bash will replace it with the value of the variable a
, or an empty string if it is unset.
If $
needs to be in the password, then it needs to be in single quotes.
./adduser_script username 'password$@aaa'
Special Characters in MySQL bash statement causing fail
This is a shell issue. In the example you show, the characters !!
are being processed by shell history expansion before they are sent to the mysql client. So you are setting the password:
1234cd srcABC^@DEFGH
Assuming cd src
was the command you ran before this one. !!
is replaced with the previous command in your shell history.
There are lots of special characters in the shell that cause various expansion effects inside double-quoted strings.
You can read man bash
:
There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.
The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.
On systems that can support it, there is an additional expansion available: process substitution.
To master shell programming, you basically need to study all of these and understand which ones work inside different types of quotes.
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.
Related Topics
How to Run Multiple Programs in a Sequence
How to Start/Restart/Stop Apache Server on Linux as Non-Root User
How to Disable Hardware Prefetcher in Core I7
Which Capabilities Are Needed for Statx to Stop Giving Eperm
Shell Script Issue with Filenames Containing Spaces
How to Move First Column to Last Column in Unix
How to Set Firefox Binary Path of Firefox in Selenium in Linux
How to Make My Makefiles Better
Segmentation Fault with a Variable in Section .Data
Why Does Script Not Recognize File Extension
Use Bash Variable Within Slurm Sbatch Script
Find Command Find Directories That Were Created After a Certain Date Under Linux/Cygwin
Are the 'Dot' and 'Dot Dot' Files in Unix and Linux Real Files
Multiple -A with Greater Than/Less Than Break Bash Script
Random Alphanumeric String Linux Swift 3