Reputation: 1260
I swear I have looked and looked and looked. If I've missed the answer to this somewhere, I apologize; it means my search-fu failed me, not that I haven't tried.
I'm relatively new to bash scripts (:sigh: newbie), but I'm trying to write one that takes some input from the user and uses it in another command. My problem is that the other command needs to have any special characters in the user input escaped.
The basic form of the code is as follows:
#!/bin/bash
echo "Enter info:"
read _INFO
othercommand info=$_INFO
Between the read
and othercommand
lines, I need to massage _INFO
so that any special characters - spaces, single and double quotes ... pretty much any non-alphanumeric character, really - are escaped. For instance, an input of this pipe: | is my info!
should become this\ pipe\:\ \|\ is\ my\ info\!
Note: I cannot put quotation marks - single or double - into the othercommand
line, as it causes the command to fail. The info string needs to go as is, except escaped.
I've tried using the string substitution macro in various ways (here are some examples that only check for spaces):
_INFO = ${$_INFO// /\ }
_INFO = ${$_INFO// /\\ }
_INFO = ${$_INFO//" "/"\ "}
_INFO = ${$_INFO//" "/"\\ "}
_INFO = ${$_INFO//' '/'\ '}
_INFO = ${$_INFO//' '/'\\ '}
but I keep getting "bad substitution" errors.
So, not only is this too specific (only handles spaces) but it doesn't work anyway. How do I do this?
If I have to use sed
or awk
or something else not native to bash script-handling, I'd prefer to be given the exact line I'd need to use, as I'm entirely unfamiliar with them. (:sigh: newbie)
Upvotes: 1
Views: 3476
Reputation: 46823
You can try printf
for that:
printf -v _INFO '%q' "$_INFO"
Upvotes: 2
Reputation: 10653
Correct way is:
_INFO=${_INFO//[^a-zA-Z]/}
There is only one way to filter user input: use a whitelist. Blacklisting is never going to work because you can't guess all of the characters that can come into mind of the user, especially in unicode. So if you want to be safe then use a list of allowed characters.
Upvotes: 0
Reputation: 75478
I think this is the proper form for that:
_INFO=${_INFO// /\ }
_INFO=${_INFO// /\\ }
_INFO=${_INFO//" "/"\ "}
_INFO=${_INFO//" "/"\\ "}
_INFO=${_INFO//' '/'\ '}
_INFO=${_INFO//' '/'\\ '}
When using parameter substitution form ${parameter/pattern/string}
, you shouldn't add $
before your parameter inside {}
.
See more about parameter expansion here: http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
Upvotes: 1