Page 3 of 3

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 08 May 2014 13:04
by penpen
dbenham wrote::shock: My brain hurts
(...)
Also, within parentheses, it only works as a comment if it follows a label or label comment.
If the above causes headaches (sorry for that), then try this :twisted: proof that no label (comment) is needed, but another caret (at least under win 7 home 64 bit):

Code: Select all

@echo off
(
   echo(What do you expect to see? It's magic.
^
 ^

   echo(Test 1: Do you think you can see me?.
   echo(Hello caret1!
^
  ^

   echo(Test 2: Do you think you can see me?.
   echo(Hello caret2!
)

penpen

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 08 May 2014 16:57
by Sponge Belly
Hi Dave and Penpen!

Good effort, but I’ve uncovered something even more obscure about echo. ;-)

Turns out if the last character in a file is SUB (Ctrl-Z) and echo is used to append to the file, the SUB is clobbered.

If anyone can find a use for this, please let us know.

- SB

PS: Same goes for appending to a file with set /p.

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 08 May 2014 18:38
by Liviu
penpen wrote:no label (comment) is needed, but another caret (at least under win 7 home 64 bit)

Confirmed under xp.sp3 as well.

Code: Select all

@echo off

^

echo this line is ignored
echo this line is executed

(
^
^

echo this line is ignored
echo this line is executed
)

Sponge Belly wrote:Turns out if the last character in a file is SUB (Ctrl-Z) and echo is used to append to the file, the SUB is clobbered.
It's the append ">>" redirection that loses the Ctrl-Z, not echo or set/p in particular. For example, if file "some.txt" ends with a Ctrl-Z and you do a "dir >>some.txt" then the Ctrl-Z is dropped, too. Not very surprising, since Ctrl-Z a.k.a. EOF (end of file) in DOS-world is known to have special treatment in text related scenarios.

Liviu

P.S. [ EDIT - added this paragraph ] One other thing to note is that the lines above marked as "ignored" seem to be fully parsed, in fact, just not executed for whatever reason. Replacing "echo this line is ignored" with "echo this line is & ignored" causes an error "'ignored' is not recognized..." - showing that the line was parsed, and was even parsed beyond just the first token.

This is relevant because it lessens the chances that the trick could be useful for macro comments. In that case, it's about what's parsed on the right-hand side of the "set" command, not execution. Surely doesn't mean it's impossible, and wish someone proves me wrong ;-) but I couldn't find the right incantation to get the "rem" lines ignored even in a plain vanilla example like this.

Code: Select all

@echo off

set var=line-1^

line-2^

rem comment-2^

line-3^

rem comment-3.a^

rem comment-3.b^

line-4

set var

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 09 May 2014 02:16
by jeb
There isn't much magic here.

I think it's more or less obvious :wink:

Mainly it's the normal escaping logic.

Code: Select all

^

something

Will be shrinked to <LF>something

So you get commands preceded with a <LF>.

Code: Select all

@echo off
SET LF=^


REM ***
echo #1
^

#1 ignore this

echo #2
^%LF%%LF%Same as #1

(
echo #3
:label3
^

ignore this

echo #4
:label4
^%LF%%LF%Same as #3
)

I suppose the <LF> doesn't stop the parser in the special character phase as the <LF> is an escaped version.
But later a <LF> seems to be a valid command without any effect.


penpen wrote:If the above causes headaches (sorry for that), then try this :twisted: proof that no label (comment) is needed, but another caret (at least under win 7 home 64 bit):
Code:
@echo off
(
echo(What do you expect to see? It's magic.
^
^

echo(Test 1: Do you think you can see me?.
echo(Hello caret1!
^
^

echo(Test 2: Do you think you can see me?.
echo(Hello caret2!
)

Even this can be reduced to
Test1
<escaped space><LF>echo Test1

Test2
<escaped space><normal space><LF>echo Test1


There are only some cases left with <LF> in combination with labels and parenthesis.
There it's possible that the first token of a line can be dropped.

Code: Select all

@echo off
(
^

rem echo You can see this!
)


jeb

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 14 May 2014 05:49
by Sponge Belly
Hi Liviu!

Thanks for the explanation.

But why doesn’t…

Code: Select all

(call;>>file.txt)


clobber the SUB at the end of file.txt?

- SB

Re: ECHO. FAILS to give text or blank line - Instead use ECH

Posted: 14 May 2014 20:47
by Liviu
Sponge Belly wrote:But why doesn’t…

Code: Select all

(call;>>file.txt)
clobber the SUB at the end of file.txt?

Because 'call;' outputs nothing at all. You can check the timestamps of 'file.txt' to see that it wasn't modified. The SUB is only clobbered if there is something actually being appended to the file.

Liviu

Re: ECHO. FAILS to give text or blank line - Instead use ECHO/

Posted: 30 Jan 2018 08:56
by dbenham
While trying to refine the rules for how the batch parser works in general, I discovered some new info about this topic.

First, at the bottom of this post I began to suspect some previous statements in this thread were wrong. jeb then confirmed the inaccuracy and provided corrected information.

I then refined some proposed rules on how the batch parser determines if a command is an internal or external command. These rules enable me to predict the following:

A safe character to follow ECHO should be any token delimiter that is not white space. That leads me to predict that all of the following should be good:

Code: Select all

echo(
echo=
echo,
echo;
But ( is only a command token delimiter in phase 2. So ECHO( cannot be used within a delayed expansion macro.
Also, ( is not a command token delimiter when it follows an unexecuted label within a parenthesized block. So ECHO( cannot be used there.

But ECHO= ECHO, and ECHO; should always be safe.

I've run some quick tests, and so far, this all seems to be true :D

Edit
Actually, they are not always safe, because I don't think a safe form exists for CALL ECHO.
All of the following will call ECHO.BAT if it exists in the current directory or the PATH:

Code: Select all

call echo=
call echo,
call echo;
call echo(

Dave Benham

Re: ECHO. FAILS to give text or blank line - Instead use ECHO/

Posted: 30 Jan 2018 09:37
by jeb
dbenham wrote:
30 Jan 2018 08:56
A safe character to follow ECHO should be any token delimiter that is not white space. That leads me to predict that all of the following should be good:

Code: Select all

echo(
echo=
echo,
echo;

But ( is only a command
Quite a nice try :wink:, but not safe for content.

Code: Select all

echo(/?
echo=/?
echo,/?
echo;/?
Only "echo(/?" is able to show "/?", all others show the HELP of echo.

jeb
PS: I edited the incorrect description in the old post

Re: ECHO. FAILS to give text or blank line - Instead use ECHO/

Posted: 30 Jan 2018 10:02
by dbenham
Of course. That makes sense.

When ECHO sees ;/? or ,/? or =/? it sees a token delimiter and then a string beginning with help option. So it prints help.

But (/? does not start with a token delimiter, so the /? is masked. Then the leading character is stripped and the remainder is printed.

Oh well. At least things make sense now.


Dave Benham