Page 1 of 1

ComSpec strange behaviour

Posted: 09 Mar 2016 02:41
by jeb
Hi,

base on the post SO: Executing command with FOR /F — “command not found”.
I tested the behaviour of ComSpec.

If you open a new cmd.exe window and try

Code: Select all

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\>set ComSpec=XXX

C:\>FOR /F %A in ('set APP') do @echo %A
Der Befehl "set test" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:\>set ComSpec=C:\windows\system32\cmd.exe

C:\>FOR /F %A in ('set APP') do @echo %A
Der Befehl "set test" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.


Okay the first FOR /F fails as ComSpec is invalid, but why the second FOR fails too?

Next test in a fresh cmd.exe window

Code: Select all

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\>FOR /F %A in ('set App') do @echo %A
APPDATA=C:\Users\Jan

C:\>set ComSpec=XX

C:\>FOR /F %A in ('set App') do @echo %A
APPDATA=C:\Users\Jan


Wow :o, even the second FOR works!

It seems that ComSpec will be cached internally when it's used the first time.

Re: ComSpec strange behaviour

Posted: 09 Mar 2016 03:05
by jeb
Some more tests show that the cached value will only be used for FOR/F,
but for pipes the ComSpec variable is used.

Code: Select all

C:\>set ComSpec=XX

C:\>FOR /F %A in ('set APP') do @echo %A
Der Befehl "set APP" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:\>echo Pipe | more
Der Befehl ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:\>set ComSpec=C:\Windows\System32\cmd.exe

C:\>FOR /F %A in ('set APP') do @echo %A
Der Befehl "set APP" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:\>echo Pipe | more
Pipe


And the Start command seems to ignore ComSpec at all

Re: ComSpec strange behaviour

Posted: 09 Mar 2016 03:08
by einstein1969
Nice find! :)

Re: ComSpec strange behaviour

Posted: 09 Mar 2016 03:31
by foxidrive
That's interesting jeb! I tested the comspec here when commenting in that thread, and noticed that I had to change comspec twice before the expected issue showed itself. You delved further, when I just shrugged my shoulders. :D

Good work.

Re: ComSpec strange behaviour

Posted: 09 Mar 2016 10:04
by penpen
The above lead me to the idea to create a "xx.bat":

Code: Select all

Z:\>> xx.bat echo %comspec% %*

Z:\>set comspec=xx

Z:\>echo Pipe | more

Z:\>C:\Windows\system32\cmd.exe /S /D /c" echo Pipe "
Pipe

Z:\>echo Pipe | more | more

Z:\>C:\Windows\system32\cmd.exe /S /D /c" echo Pipe "
Pipe


Z:\>(set comspec=xx&echo Pipe |more) | more
Der Befehl ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

I was a liitle bit surprised, that the last command is executed in the actual cmd-instance (i thought they all are executed in a new task).
Second unexpected is, that the last command doesn't find xx.bat (even if i copy it to c:\windows\system32).
(And my hope to see, what the cmd shell executes on for /F was destroyed: just doesn't work even with xx.bat.)

penpen

Re: ComSpec strange behaviour

Posted: 10 Mar 2016 06:31
by jeb
Hi penpen,

I suppose your results are a bit wrong
Your xx.bat look like

Code: Select all

echo C:\Windows\system32\cmd.exe %*

Instead of

Code: Select all

echo %comspec% %*


I modified xx.bat for more informations

Code: Select all

@echo off
setlocal DisableDelayedExpansion
set prompt=#
@echo ON
REM #### xx.bat startet ####
REM #### Content of %%0 : %0
REM #### Content of %%~0: %~0
REM #### Content of %%~f0: %~f0
REM #### %%*: '%*'
REM #### %%1: '%1'
REM #### %%2: '%2'
REM #### %%3: '%3'
REM #### %%4: '%4'
REM #### %%5: '%5'
@echo off
endlocal


I can't reproduce your last error, I simply get

Code: Select all

C:\temp>set comspec=xx

C:\temp>(set comspec=xx&echo Pipe |more) | more

#REM #### xx.bat startet ####

#REM #### Content of %0 : .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

#REM #### Content of %~0: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

#REM #### Content of %~f0: C:\temp\xx.bat

#REM #### %*: '/S /D /c" ( set comspec=xx & echo Pipe | more )"'

#REM #### %1: '/S'

#REM #### %2: '/D'

#REM #### %3: '/c" ( set comspec=xx & echo Pipe | more )"'

#REM #### %4: ''

#REM #### %5: ''


It's interessting, that in %0 is garbage like 'COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC'

Re: ComSpec strange behaviour

Posted: 10 Mar 2016 08:06
by penpen
jeb wrote:I suppose your results are a bit wrong
Your xx.bat look like

Code: Select all

echo C:\Windows\system32\cmd.exe %*

Instead of

Code: Select all

echo %comspec% %*
I checked my results with no error.
I guess you couldn't reproduce the error because there is no "echo" in my "xx.bat"; it only contains:

Code: Select all

C:\Windows\system32\cmd.exe %*


penpen

Re: ComSpec strange behaviour

Posted: 10 Mar 2016 12:12
by jeb
Ok penpen, I missunderstood you completly :(

But to output some informations could be a good idea :idea:

If you change your xx..bat to

Code: Select all

@echo off
echo ComSpec '%~nx0' startet  > con
setlocal

set "prompt=$S"
(
@echo on
for %%a in (1) do REM ---| %* |--- REM
) > con
@echo off
echo Starting %%* now > CON
C:\Windows\system32\cmd.exe %*


Then you got for your last test
C:\temp>(set comspec=xx&echo Pipe |more) | more
ComSpec 'xx.bat' startet

REM ---| /S /D /c" ( set comspec=xx & echo Pipe | more )" |--- REM
Starting %* now
Der Befehl ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.


So the inner pipe creates the problem, when you build a second file by copy xx.bat "xx .bat"
Even this works

Code: Select all

C:\temp>(set comspec=xx&echo Pipe |more) | more
ComSpec 'xx .bat' startet

 REM ---| /S /D /c" ( set comspec=xx & echo Pipe | more )" |--- REM
Starting %* now
ComSpec 'xx .bat' startet

 REM ---| /S /D /c" echo Pipe " |--- REM
Starting %* now
Pipe


The only problem was that the `set comspec=xx &` creates 'comspec=xx<space>'

Re: ComSpec strange behaviour

Posted: 13 Mar 2016 08:45
by penpen
Ah :oops:
I missed the extra space... .

jeb wrote:But to output some informations could be a good idea :idea:
Yes, so %0 is displayed in the error message ("Der Befehl "%0" ist entweder....").
Maybe this could be useful to know in future.

Btw:
jeb wrote:It's interessting, that in %0 is garbage like 'COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC'
This output made me create the xx.bat file:
Somehow the content of "PATHEXT" variable content is displayed (==the garbage).
But it seems it couldn't be used to start "xxyy.bat":

Code: Select all

Z:\>> xx.bat echo @echo xx.bat #  %* #  %~0

Z:\>set "pathext=yy.bat;%pathext%"

Z:\>set comspec=xx

Z:\>echo pipe|more
xx.bat #  /S /D /c" echo pipe" #  yy.bat;.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

Z:\>> xxyy.bat echo echo xxyy.bat #  %* #  %~0

Z:\>echo pipe|more
Die Datei "Z:\xxyy.bat" kann nicht gefunden werden.
The error message is just a little bit irritating...
the file "Z:\xxyy.bat" couldn't be found only if it exists ... .


penpen

Re: ComSpec strange behaviour

Posted: 02 Jan 2018 17:37
by npocmaka_
looks like for /f presets the comspec (along with prompt and pathext) - https://stackoverflow.com/questions/480 ... environmen
and when comspec is not specified the pipe fails:

Code: Select all

set "comspec="
::this will print C:\WINDOWS\system32\cmd.exe
for /f %%a in ('echo %comspec%') do echo %%a
::this will crash the command window
break|break
COMSPEC , PROMPT and PATHEXT are interesting in other meanings too.
Looks COMSPEC changes are (in some degree) immideate and does not happen after the line/codeblock is finished

this will crash the command prompt:

Code: Select all

(

	set "comspec="
	echo %comspec%
	break|break
)
and this too:

Code: Select all

set "comspec=" & break|break

Re: ComSpec strange behaviour

Posted: 03 Jan 2018 04:34
by penpen
The article from wdonahue (@stackoverflow) is a bit irritating.

You should get all variables set in:
- User Variables: HKEY_CURRENT_USER\Environment
- System Variables: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

Has he cleared the "registry pre-setting", when he got this results?


penpen

Re: ComSpec strange behaviour

Posted: 03 Jan 2018 05:04
by npocmaka_
The script he's posted has the same behavior on my machine without changing anything in the registry - variables are "deleted" just for the current cmd session.

The interesting part is that the FOR /F starts a new instance of cmd (at least when an internal command is called) and it pre-sets PROMPT,COMSPEC and PATHEXT . But why only these three ( have no idea about the special variables like =:C and =:: ) ?

Re: ComSpec strange behaviour

Posted: 03 Jan 2018 06:20
by jeb
It's strange.
The default values are only loaded, when the variable is undefined, not when it's only changed to another value.

And the pipe loads also the default values for PATHEXT and PATH.
For COMSPEC it fails, probably because COMSPEC is needed before the default load function is called.

I tested it with

Code: Select all

@echo off
setlocal EnableDelayedExpansion
FOR /F %%L in ('break') do echo Dummy to "cache" comspec

set var=pathext
echo Original value of %var% is "!%var%!"
echo(
call :test %var% ".com;.exe"
call :test %var% ""
exit /b


:test 
echo ------ set %1 to "%~2" ------
setlocal
set "%~1=%~2"
echo ******* Testing FOR /F ******* 
for /F "delims=" %%L in ('set %~1') do echo ###FROM FOR: %%L
echo(
echo ******* Testing PIP    ******* 
break | set %~1
echo(
exit /b