0

I've read this post, which helps in most cases, and this post, which seems a duplicate, but I couldn't get it to work.

Disclaimer: disabling/enabling delayed expansion works as workaround but that's annoying to do, unless the whole script can be disabled. I am curious whether there's a more direct approach.

I use this brilliantly simple colorEcho script and sometimes I just want to print an exclamation mark. As that post shows (but fails to address), it doesn't print the exclamation mark.

Repro:

@echo Off
SETLOCAL EnableDelayedExpansion

rem Initialize backspace-space-backspace
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do     rem"') do (
  set "DEL=%%a"
)

rem Using it
call :colorEcho 0a "Give me an exclamation!"
echo.
pause
GOTO :EOF

rem The actual color-print hack
:colorEcho
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1i

Gives:

enter image description here

I've tried:

  • call :colorEcho 0A "Ex^!" and variants like ^^^!
  • first set excl=^^! then CALL :colorEcho "Foo!excl!"
  • some variants with more/less escaping
  • created a simplified routine without colorEcho, but it ran into the same issues:

    :test
    rem How to call :test with %1 containing an excl mark
    echo %1
    exit /B
    

Perhaps this is not possible, and I should either not want to output an exclamation mark, or I should use the already mentioned DisableDelayedExpansion. Any ideas?

Abel
  • 56,041
  • 24
  • 146
  • 247
  • Since your script isn't using delayed expansion just remove that line! – Compo Oct 28 '17 at 17:58
  • @comp, that's the whole point, I can't. To keep the question simple, I tried to create a minimal repro example, I need delayed expansion in my main scripts. If I didn't need it, I would use the mentioned workaround, of course ;). I updated the q., for emphasising this, thanks – Abel Oct 28 '17 at 18:05
  • You don't need it enabling everywhere though, _as can be seen above_, so keep it disabled until you need it enabling. That could be fairly simple or really difficult, but without seeing your entire script, I couldn't say which of those is true. – Compo Oct 28 '17 at 18:13
  • @compo, that's the workaround currently in use if I absolutely need it and it's trivial enough. But I like to be able to pass a param with an exclamation mark. If it's truly not possible, I'll live with it. But I expect there's a way that I'm missing. – Abel Oct 28 '17 at 18:26
  • Strangely, my machine showed no newline between the green text and the `pause` output. Side-effect of reductio-ad-minimum? – Magoo Oct 29 '17 at 02:49
  • @magoo, no, just a copy/paste idiosyncrasy, `colorEcho` doesn't issue a newline by default. Thanks, fixed now. – Abel Oct 29 '17 at 08:44
  • @Compo, I just realized that it can be enabled/disabled _per procedure/label_. With that, I can just disable it inside the `:colorEcho` procedure, and it _just works_. Thanks for pointing me in the right direction! – Abel Oct 29 '17 at 17:54

1 Answers1

2

You can use this

set "ex=^^^!"
call :colorEcho 0a "Give me an exclamation%%ex%%"

But better would be to use call with a variable 9nstead of content. Because the call command has nasty side effects

jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks, this seems to work for the trivial case. But in my "main batch file" in `colorEcho`, I assign the variable first to another variable (an update after I posted this), which I think results in double-interpretation of the `%%` (i.e. I have `set TMPFILENAME=%~2`). Can you elaborate on what you mean with "call with variable vs content"? – Abel Oct 29 '17 at 16:11
  • While I still do not understand your last "but better" comment, I just realized, prompted by your answer, that if I disable expansion _only for that procedure_, it just works with normal escaping. I.e., add `setlocal DisableDelayedExpansion` right below the `:colorEcho` label. Can't believe I didn't think of that previously! Since this command is local to the procedure, only those procedures that require passing in excl marks need to be written without expansion. – Abel Oct 29 '17 at 17:52