Page 1 of 1

KEYS as boolean variable within brackets and without delayed expansion

Posted: 21 Jan 2016 07:51
by npocmaka_
Nothing useful , just observation over KEYS internal state and how it differs from ECHO.
KEYS changes its state even if it's called within brackets or in conditional execution statements and to child threads/processes spawned with pipes or FOR (unlike ECHO):

Code: Select all

@echo off

setlocal disableDelayedExpansion

set "if_on=for /f "tokens=3" %%# in ('keys') do if %%#==on. "
set "if_off=for /f "tokens=3" %%# in ('keys') do if %%#==off. "

rem :: echo state cannot be examined so easy
::for /f "tokens=3" %%# in ('echo') do echo %%#
::echo|for /f "tokens=3" %%# in ('more') do echo %%#
::echo|find "on."
(

   keys on
   %if_on% echo Should be displayed
   %if_off% echo Should be not
   keys off
   %if_off% echo Should be displayed
   %if_on% echo Should be not
   (
     keys on
   )
   %if_on% echo Should be displayed
   %if_off% echo Should be not

)


For sure this is slower than IF DEFINED (which also works in brackets context)
KEYS state can be examined also with pipes and FIND/FINDSTR - but probably will be slower.

The only case where this eventually (but probably will be never needed) can be easier for use is if IF DEFINED is piped. Rather is just

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 21 Jan 2016 13:53
by dbenham
The ECHO state also changes within a code block, but commands that have already been parsed are not echoed if the state was OFF before the block was parsed. The only exceptions are the DO commands within a FOR loop.

Code: Select all

@echo off
(
  echo on
  echo
  for %%. in (.) do REM This command should echo
  echo off
  echo
  for %%. in (.) do REM This command should not echo
)

--OUTPUT--

Code: Select all

ECHO is on.

D:\test>REM This command should echo
ECHO is off.


Dave Benham

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 22 Jan 2016 03:42
by npocmaka_
The thing is you cannot detect echo state without temp file (at least I couldn't find a way ):
( And I think it's impossible to detect @() block )

Code: Select all

@echo off

(
   (echo)|more
   for /f "tokens=*" %%a in ('echo') do echo %%a
   
)


For and pipes resets its state.

And here I saw your echo_on macro (great trick by the way :) ).

Because pipe resets the state of the echo also this can be used:

break|for %%a in (.) do echo something


without a need to add echo off after using it (but probably will hit the performance a little bit).

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 05:00
by npocmaka_
And VERIFY state also cannot be examined without a temp file:

Code: Select all

  for /f "tokens=3" %%a in ('verify') do @echo -%%a- 
  verify on
  for /f "tokens=3" %%a in ('verify') do @echo -%%a-


this will always print off.

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 06:44
by foxidrive
Gee, it's even worse than that!

Code: Select all

@echo off
verify on
verify|find "is"
verify
  pause



VERIFY is off.
VERIFY is on.
Press any key to continue . . .

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 06:46
by npocmaka_
foxidrive wrote:Gee, it's even worse than that!

Code: Select all

@echo off
verify on
verify|find "is"
verify
  pause



VERIFY is off.
VERIFY is on.
Press any key to continue . . .


Yes.The case is the same as ECHO.
The pipes creates new threads/cmd contexts (on both sides) which are with some default states reset.Including ECHO and VERIFY

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 07:05
by dbenham
By default, there is no KEYS environment variable defined.

But issuing KEYS ON will set variable KEYS=ON, and KEYS OFF will set KEYS=OFF. This is true, even if you preset a KEYS variable to some bogus value.

Unfortunately, ECHO and VERIFY do not follow this same behavior. :(


Dave Benham

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 08:21
by jeb
There could be an echo state check without temporary files, but currently I only get the half.

Code: Select all

@(
  for %%A in (1) do break
) 1>&0


In the case of echo off it works without any error message or side effect.
With echo on it outputs (in german)

Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.


but: Nor it changes the errorlevel neither I can get the || logic working.

Code: Select all

@(
  for %%A in (1) do break || ECHO No Effect
) 1>&0 || ECHO No Effect


Perhaps someone get a better idea.

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 12:02
by dbenham
jeb wrote:There could be an echo state check without temporary files, but currently I only get the half.

Code: Select all

@(
  for %%A in (1) do break
) 1>&0


In the case of echo off it works without any error message or side effect.
With echo on it outputs (in german)

Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.
Das System kann nicht auf das angegebene Gerät schreiben.


Great idea, and so close...

jeb wrote:but: Nor it changes the errorlevel neither I can get the || logic working.

Code: Select all

@(
  for %%A in (1) do break || ECHO No Effect
) 1>&0 || ECHO No Effect


Yep, I ran into basically the same issue at I/O error detection is broken The only way I was able to detect an I/O error was via a temporary file... Aaargh :twisted:

It really seams like a dead end.


Dave Benham

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 15:52
by npocmaka_
I still have troubles to get this redirection tricks...

Whats the point to send 1 to 0 ?

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 27 Jan 2016 15:57
by dbenham
The redirection of stdout to stdin "succeeds", but any attempt to actually write to stdin will of course fail.

When ECHO is off, there is no output, so no error message.

When ECHO is on, then the echo of the command fails and we get error messages. But it doesn't do us any good because we have no way to programmatically detect the error message unless we redirect stderr to a temp file.

It is possible to do staged redirection and effectively capture stderr with FOR /F, but the FOR /F launches a new cmd session with the ECHO defaulting to ON, regardless of the parent state. It's all very frustrating.


Dave Benham

Re: KEYS as boolean variable within brackets and without delayed expansion

Posted: 28 Jan 2016 02:35
by npocmaka_
dbenham wrote:The redirection of stdout to stdin "succeeds", but any attempt to actually write to stdin will of course fail.

When ECHO is off, there is no output, so no error message.

When ECHO is on, then the echo of the command fails and we get error messages. But it doesn't do us any good because we have no way to programmatically detect the error message unless we redirect stderr to a temp file.

It is possible to do staged redirection and effectively capture stderr with FOR /F, but the FOR /F launches a new cmd session with the ECHO defaulting to ON, regardless of the parent state. It's all very frustrating.


Dave Benham


Aha :!: thanks.