Batch: Escaping with caret
Asked Answered
S

2

12

I've always hated batch and I still do, even for the most simple things I prefer C or PHP/Perl. But this time I could not go without it, ****sigh****.

I wanted to redirect an echo command to an other command. For example:

echo example | more

but I also wanted to be able to use special characters in the echo part of the pipe:

echo & | more

Which of course did not work. So I tried:

echo ^& | more

Which did not work either. Then by trial-and-error I found:

echo ^^^& | more

and that worked. But as interested programmer I wonder why. Why did ^& not work and ^^^& did?

Storiette answered 25/6, 2012 at 16:52 Comment(4)
I found this, maybe this is helpful for you? #3813870Garrow
+1, even though you slight the beauty of almighty batch, LOL. I understand batch is extremely quirky, inconsistent, and under-documented. But then I guess the challenge is why I have so much fun with it :-)Adytum
@dbenham, Are there any attempts at documenting batch syntax from Windows?Bullfighter
@Bullfighter - https://mcmap.net/q/13959/-how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/1012053Adytum
A
14

The reason has to do with how Windows implements pipes - Each side of the pipe is executed in its own CMD shell. Your command echo ^& | more actually attempts to execute

C:\Windows\system32\cmd.exe /S /D /c" echo & "

on the left and

C:\Windows\system32\cmd.exe /S /D /c" more "

on the right. You can see why the left hand side fails - trying to echo an unescaped &. The escape was consumed by the initial parsing phase before the actual left side is executed.

It is also easy to see why your solution works. The left side of echo ^^^& | more becomes

C:\Windows\system32\cmd.exe /S /D /c" echo ^& "

There are many subtle complications when working with Windows pipes. Refer to Why does delayed expansion fail when inside a piped block of code? for more info. The selected answer has the best info, but I recommend reading the question and all answers to get the context of the selected answer.

Adytum answered 25/6, 2012 at 17:17 Comment(0)
E
5

The first ^ is escaping the ^ character itself (the second ^) and the third ^ is escaping the &.

When you run a command like ECHO ^& | MORE, the ^& is replaced with & by the shell before the output is piped to MORE.

So, when you run ECHO ^^^& | MORE, the shell replaces ^^ with ^ and the ^& with & and then pipes the output to MORE.

Epigrammatist answered 25/6, 2012 at 17:16 Comment(1)
Your first paragraph's good for a tongue-twister...Bullfighter

© 2022 - 2024 — McMap. All rights reserved.