pdg pdg - 7 months ago 15
Bash Question

double backslashes of sed single-quoted command inside command substitutions get translated to a single backslash

printf '%s' 'abc' | sed 's/./\\&/g' #1, \a\b\c
printf '%s' "`printf '%s' 'abc' | sed 's/./\\&/g'`" #2, &&&

The expression inside the second backticks returns
, and we have
printf '%s' "\a\b\c"
, so it should print
My question is: why does the second script print

I can get the second script work (prints
) by prepending each backslash with another backslash, but I don't know why it's needed.

One related question:
why does this single quoted string get interpreted when it's inside of a command substitution


This is a good example to show difference between back-tick and $(cmd) command substitutions.

When the old-style backquoted form of substitution is used, backslash retains its literal meaning except when followed by "$", "`", or "\". The first backticks not preceded by a backslash terminates the command substitution. When using the "$(COMMAND)" form, all characters between the parentheses make up the command; none are treated specially.


So take a look your example, I used echo instead of printf:

kent$  echo 'abc' | sed 's/./\\&/g'

kent$  echo -E "`echo 'abc' | sed 's/./\\&/g'`"

kent$  echo -E "$(echo 'abc' | sed 's/./\\&/g')"                    

You can see, the back-tick command substitution made your \\ as single \, thus together with the followed & it became \& (literal &)

Note that I used echo -E in order to disable the interpretation of backslash escapes so that the \a\b\c could be printed out.