3

The command

echo `echo \\\\\\\z`

is from this book , I don’t understand why it prints

\\z

when it get executed via the bash script.

I think it should print

\\\z
6
  • It does if you use $(...) in place of backticks.
    – Kusalananda
    Aug 7, 2021 at 10:36
  • Please check whether you have the right number of backslashes in your question. I see mentioning of \\z as output in the document that you link to, not \\\z.
    – Kusalananda
    Aug 7, 2021 at 11:09
  • 1
    @ImHere, does that linked question really answer the question about why it behaves like this in backticks? It seems to talk only about $(), which behaves differently here (doesn't make a difference with the three-backslash string like there, though)
    – ilkkachu
    Aug 7, 2021 at 13:07
  • 1
    The command you mentioned in your question prints \z on a shell that correctly implements POSIX.
    – schily
    Aug 8, 2021 at 14:55
  • @schily Yes, that's correct. Try dash -c 'echo `echo \\\\\\\z`'
    – user232326
    Aug 8, 2021 at 21:01

2 Answers 2

6

Backticks effectively give you double processing of the backslashes. (Once when the main command line is processed, and another time when the command in the command substitution is.)

Like Kusalanda says, that's different for the $(..) command substitution.

First, let's note that we appear to be talking about Bash's echo, which by default doesn't process backslash escapes itself, so e.g. echo '\\' passes \\ to echo which prints \\. If you used an echo that deals with backslashes itself (like Bash with shopt -s xpg_echo, or Dash, or zsh), you'd get that last \\ turned into \ and \z as the output.


Bash's manual says:

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by [a dollar sign, backtick or backslash].

So, in the command

echo `echo \\\\\\\z`      # 7 backslashes

the \\ pairs get first reduced to single \s, and the \z stays as \z (it's not followed by any of the three, so that backslash is literal). Then the command in the backticks runs through the shell again.

So the command in the command substitution ends up as

echo \\\\z                 # 4 backslashes

where the \\ pairs are reduced to single \s, and the argument to echo becomes \\z (which is printed unchanged through the two echos, see caveat above).

You can see a similar result with a dollar sign, e.g.:

var=foo
echo `echo \$var`

prints foo.

POSIX has also a weird example with single quotes:

echo `echo '\$x'`

prints $x. (the single quotes don't protect the $)


The $(...) form of command substitution is saner, its contents only get processed once, so:

echo $(echo \\\\\\\z)           # 7 backslashes

prints \\\z (3), and

var=foo
echo $(echo \$var)

prints $var.

Also see:

1
  • Backticks effectively give you a kind of double processing of the backslashes. Only the double quoted type is equivalent.
    – user232326
    Aug 9, 2021 at 7:25
-1

The initial echo command is handled by the shell, and so it correctly sees the multiple \ and reduces them to echo \\\z.

At this point, the shell is no longer involved.

The echo command then sees \\\, and so it it reduces that to the single \, ie, you want a literal \.

There is no need to escape the last \, and so that then reduces to \\\z.

5
  • 1
    Can you explain the difference between echo `echo \\\\\\\z` and echo $(echo \\\\\\\z)?
    – Kusalananda
    Aug 7, 2021 at 10:39
  • I assume the shell is involved at both reductions. in the original question, it is only involved once
    – Bib
    Aug 7, 2021 at 10:42
  • echo does not care about backslashes at all unless used with -e or the xpg_echo option is set.
    – Kusalananda
    Aug 7, 2021 at 11:06
  • Lost count, or deliberate to make it look wrong. Please put it back to the way it way. You have access to the edit history.
    – Bib
    Aug 7, 2021 at 11:45
  • 1
    @Bib, you have access to the edit history too, it says "Rollback to Revision 1" in the last one. Also, of course you can compare with the first version stored there. Now, I'm not sure why you'd think I'd have messed it up on purpose, but believe me, that was not what I did. I only noticed when editing that you have empty quoted parts there, in "to the single '', ie, you want a literal ''.", and I'm not sure if that's what you intended to write, so you might want to take a look yourself
    – ilkkachu
    Aug 7, 2021 at 11:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .