Safe REM with ampersand

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Safe REM with ampersand

#1 Post by jeb » 14 Jan 2016 09:03

Hi,

from a SO topic How to reliably use `rem` within a command line without ignoring adjacent commands?.

Is there a way for a safe REM which executes an adjacent command.

Simple, but can fail when a file named REM exists

Code: Select all

REM. comment & echo My text


There seems also a difference if there is an ampersand or not.

Code: Select all

REM^;\..\x.bat & This works
REM But not the next line, it starts x.bat in the current directory
REM^;\..\x.bat


But my tests shows that these sample works always

Code: Select all

@echo off

echo 1
REM^= \..\x.bat
echo 2
REM^/ \..\x.bat
echo 3
REM^\ \..\x.bat
echo 4
REM^: \..\x.bat

REM^= \..\x.bat & echo 4
REM^/ \..\x.bat & echo 5
REM^\ \..\x.bat & echo 6
REM^: \..\x.bat & echo 7

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Safe REM with ampersand

#2 Post by dbenham » 14 Jan 2016 10:04

Very interesting...

When I test your script on my Win 7 machine at work, every thing works.

But I swear when I tested something that I thought was equivalent on Win 10 at home, the stand-alone versions (without &) all failed. If I am correct, then this would be a somewhat shocking difference between Win 7 and Win 10. I'll double check again when I get home, or someone else with Win 10 could beat me to the punch.


Dave Benham

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Safe REM with ampersand

#3 Post by dbenham » 14 Jan 2016 10:10

The other interesting part that I remember from my tests on Win 10 at home was that something like REM^, \..\x.bat worked on the command line, but failed in a batch script.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Safe REM with ampersand

#4 Post by dbenham » 14 Jan 2016 10:51

Also, the first test fails if file "rem=.bat" exists, even on Win 7.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Safe REM with ampersand

#5 Post by dbenham » 14 Jan 2016 20:17

OK, I somehow fooled myself with my Win 10 testing. I can't find any difference in behavior on this topic between Win 7 and Win 10 - thank goodness :!: :D

Where I ran into trouble was I had multiple batch files named things line "REM .BAT", "REM;.BAT", etc. And I did not structure them in a way that let me identify which one ran.

So when I tested something like

Code: Select all

REM^; \..\x.bat
I assumed it was x.bat that was running, when actually it was "REM;.BAT" that ran. So I arrived at the wrong conclusions as to what worked and what did not.

From what I can tell, the following form: rem<C><tokenDelimiter> works always when <C> is one of [backSlash], [forwardSlash], or [colon], and <tokenDelimiter> is one of [space], [tab], [0xFF], [comma], [semicolon], or [equal]. I don't see any need to escape the <C> character.

So all of the following work, even if x.bat exists in the current directory. Note - this is not an exhaustive list of all working permutations.

Code: Select all

@echo off

echo 1
REM\ \..\..\x.bat
echo 2
REM/ \..\..\x.bat
echo 3
REM: \..\x.bat

REM\ \..\..\x.bat & echo 4
REM/ \..\..\x.bat & echo 5
REM: \..\x.bat & echo 6

echo 7
REM:;\..\x.bat
echo 8
REM:,\..\x.bat
echo 9
REM:=\..\x.bat

REM:;\..\x.bat & echo 10
REM:,\..\x.bat & echo 11
REM:=\..\x.bat & echo 12

A critical component to why the above work is that : \ and / cannot appear in file names.

One additional form that seems to work is REM^[TAB]<tokenDelimiter>, but I'm not sure why. I can get the [TAB] in a file name, but the problem cases below don't seem to matter with [TAB].

As jeb already said, REM. is no good because it fails always if a file named "REM" (without an extension) exists in the current directory.

All the other candidates can fail in a batch file because they can appear in a file name. Note - only one of the following lines can be tested at a time

Code: Select all

REM^  This fails if "REM .BAT" exists
REM^; This fails if "REM;.BAT" exists
REM^, This fails if "REM,.BAT" exists
REM^= This fails if "REM=.BAT" exists
REM^[0xFF] This fails if "REM[0xFF].BAT" exists
REM[ This fails if "REM[.BAT" exists
REM] This fails if "REM].BAT" exists
REM+ This fails if "REM+.BAT" exists
But append & echo something to each line above, and they all work.

All potential characters can fail if there is not an unescaped token delimiter afterward because of the \..\x.bat issue. The unescaped token delimiter is required to disrupt the file path parsing.

So my results are similar to what jeb reported, accept
  • I don't see any need to escape the : / or \
  • = Cannot always be used safely, even if escaped


Dave benham

Post Reply