Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have created a shell script which takes a string as input. If the string contains $ or &, then I need to replace those characters with \$ and \&. I could done that with sed command. After this I want to replace a word in a particular text file with that corresponding string.

Please see this section for more clarification.

This is my file.

test.txt

hello my root password is root.

Now, I want to change the word root with a string. The string can be anything which may include special characters like $ or &.

If I want to replace root with the string my&rootpa$$, then it should look like my\&rootpa\$\$ in text file.

This is my shell scipt

#!/bin/bash
dothis(){
    rootpass=$(echo "$1" | sed -r 's/\$/\\$/g');
    rootpass=$(echo "$rootpass" | sed -r 's/\&/\\&/g');
    echo $rootpass;
    sed -i "s/root/$rootpass/g" test.txt
}
dothis "my&rootpa$$";

This script works properly upto echo $rootpass, which means when I echo the string it will display my\&rootpa\$\$.

But in the file it looks my&rootpa$$ instead of my\&rootpa\$\$. What's wrong with the script?

Please advice.

share|improve this question
    
Please don't cross port to multiple SE sites. I see you have an answer on Super User that is correct though. –  Iain Jan 22 at 7:55
    
Hi lain, I have posted the same question at SuperUser, askubuntu also. I was in a bit hurry to get the answer. Is there any issues in this ? –  Uvais Ibrahim Jan 22 at 10:14
    
Yes, please don't do it as it fragments the answers and is frowned upon. Also as you found out you can make errors when copying them which is a nuisance. Just don't do it. –  Iain Jan 22 at 10:16
    
Thanks Lain for your concern. I am beginner in all these. –  Uvais Ibrahim Jan 22 at 10:34

3 Answers 3

up vote 2 down vote accepted

There's an extra layer of quoting lacking. In sed & has a special meaning in the replacement (stands for the matching string). So to insert a literal & you'd escape it once, and to insert a literal \&, you'd escape the backslash (\\) and the ampersand (\\&), same for the backslash before $. That gives you:

#!/bin/bash
dothis(){
    rootpass="${1//\$/\\\\$}"
    rootpass="${rootpass//&/\\\\\&}"
    echo $rootpass
    sed -i "s/root/$rootpass/g" test.txt
}
dothis 'my&rootpa$$';
share|improve this answer

You should change this line:

dothis "my&rootpa$$";

to

dothis "my&rootpa\$\$";

or using quote instead of double quotes:

dothis 'my&rootpa$$';

In your case, $$ in string my&rootpa$$ will be expanded to PID of script itself.

share|improve this answer
    
As the OP says everything OK up to the last sed command at which point $rootpass is my\&rootpas\$\$ so the problem variable expansion. –  Iain Jan 22 at 7:32

This "dothis "my&rootpa$$" uses double quotes and the "$$" at the end will be expanded to the current PID. When I execute your script, this happens:

 $ ./a.sh 
 my\&rootpa3595

...since "3595" happens to be the PID of the script. When you use single quotes (' '), the string you expected is printed:

 $ tail -1 a.sh 
 dothis 'my&rootpa$$';

 $ ./a.sh 
 my\&rootpa\$\$
share|improve this answer
    
Note the last paragraph of the question which show that the $$ isn't being expanded... Take a look at revision 1 of the OPs question it shows an incorrect sed command, I suspect other transcription errors too. –  Iain Jan 22 at 7:41
    
NOte also that you haven't done the final sed which is the problem. –  Iain Jan 22 at 7:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.