1

I have one file named `config_3_setConfigPW.ldif? containing the following line:

{pass}

on terminal, I used following commands

SLAPPASSWD=Pwd&0011   
sed -i "s@{pass}@$SLAPPASSWD@" config_3_setConfigPW.ldif

It should replace {pass} to Pwd&0011 but it generates Pwd{pass}0011.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
Rohit Kanade
  • 21
  • 1
  • 5

3 Answers3

1

The reason is that the SLAPPASSWD shell variable is expanded before sed sees it. So sed sees:

sed -i "s@{pass}@Pwd&0011@" config_3_setConfigPW.ldif

When an "&" is on the right hand side of a pattern it means "copy the matched input", and in your case the matched input is "{pass}".

The real problem is that you would have to escape all the special characters that might arise in SLAPPASSWD, to prevent sed doing this. For example, if you had character "@" in the password, sed would think it was the end of the substitute command, and give a syntax error.

Because of this, I wouldn't use sed for this. You could try gawk or perl?

eg, this will print out the modified file in awk (though it still assumes that SLAPPASSWD contains no " character

awk -F \{pass\} ' { print  $1"'${SLAPPASSWD}'"$2 } ' config_3_setConfigPW.ldif
Andrew Kay
  • 252
  • 2
  • 8
  • You're on the right track by using awk but you're using very error-prone syntax. The correct syntax for your suggested approach be `awk -F '{pass}' -v new="$SLAPPASSWD" ' { print $1 new $2 } '`. – Ed Morton Jan 14 '16 at 14:58
1

That's because$SLAPPASSWD contains the character sequences & which is a metacharacter used by sed and evaluates to the matched text in the s command. Meaning:

sed 's/{pass}/match: &/' <<< '{pass}'

would give you:

match: {pass}

A time ago I've asked this question: "Is it possible to escape regex metacharacters reliably with sed". Answers there show how to reliably escape the password before using it as the replacement part:

pwd="Pwd&0011"
pwdEscaped="$(sed 's/[&/\]/\\&/g' <<< "$pwd")"

# Now you can safely pass $pwd to sed
sed -i "s/{pass}/$pwdEscaped/" config_3_setConfigPW.ldif
Community
  • 1
  • 1
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
1

Bear in mind that sed NEVER operates on strings. The thing sed searches for is a regexp and the thing it replaces it with is string-like but has some metacharacters you need to be aware of, e.g. & or \<number>, and all of it needs to avoid using the sed delimiters, / typically.

If you want to operate on strings you need to use awk:

awk -v old="{pass}" -v new="$SLAPPASSWD" 's=index($0,old){ $0 = substr($0,1,s-1) new substr($0,s+length(old))} 1' file

Even the above would need tweaked if old or new contained escape characters.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185