Page 1 of 1
call set bug?
Posted: 14 Nov 2015 15:10
by Sponge Belly
Hello All!
Sorry I haven’t posted in a while. My mind has been… elsewhere. Anyways, could someone please explain what’s going on here?
Code: Select all
@echo off & setlocal enableextensions disabledelayedexpansion
set ^"str= hello ^&^"^& world! ^"
(call;)
call set "str1=%%str%%" && echo(success || echo(failure
set str
endlocal & goto :eof
The output says success, but str1 is not set. There is no error message and running the program with echo on sheds no light. Is there an explanation for this apparent contradiction… apart from overall Microsoft bugginess, that is?
Laters!
- SB
Re: call set bug?
Posted: 14 Nov 2015 16:50
by penpen
I don't know exactly (and actually i have no idea how to proof it), but I guess the "late expansion" of the doublequote confuses the "call"-command so that it recognizes the complete (command) string as a parameter of an empty command. The minimal example (under windows 8 ):
Code: Select all
@echo off
setlocal enableextensions disabledelayedexpansion
set doublequote="
call whatever "%%doublequote%%&"
endlocal
goto :eof
penpen
Re: call set bug?
Posted: 15 Nov 2015 05:19
by jeb
It's a problem of special characters.
In a CALL statement unescaped special characters (&, |, &&, || ) droppes the complete command.
But this is only true for some characters, other characters like (<>) will be ignored.
Code: Select all
set "var1=#1 Visible > nul"
call echo %%var1%%
set "var2=#2 Invisible & echo Invisible"
call echo %%var2%%
set "var3=#3 Invisible || echo Invisible"
call echo %%var3%%
If you escape the special characters it works, you could also quote them.
Code: Select all
set "var4=#4 Visible ^> nul"
call echo %%var4%%
set ^"var5=#5 visible "&" visble"
call echo %%var5%%
But even here exists an exception, when the special character is the last character it works but without the special characters, too.
Code: Select all
set "var6=#6 Visible ||"
call echo %%var6%%
Re: call set bug?
Posted: 18 Nov 2015 14:59
by Sponge Belly
Hi Penpen and Jeb!
Thanks for the explanations. Just one more pitfall to look out for when writing a Batch file!
On a related topic, Jeb wrote in
this post:
Code: Select all
set "safeSet=set^ ""
call %%safeSet%% var=123"
I was wondering why you didn’t just write:
Code: Select all
set "safeSet=set"
call %%safeSet%% "var=123"
Thanks in advance.
- SB
Re: call set bug?
Posted: 18 Nov 2015 15:27
by jeb
Sponge Belly wrote:On a related topic, Jeb wrote in this post:
Code:
set "safeSet=set^ ""
call %%safeSet%% var=123"
I'm impressed of this technic
, as I forgot it completly and I reinvent the wheel this year, but this time my
new technic was a bit more complex.
But now I try to answer your question
Sponge Belly wrote:I was wondering why you didn’t just write:
Code:
set "safeSet=set"
call %%safeSet%% "var=123"
The problem is that it starts a batch file named "set.bat" when it exists.
Even this fails
Code: Select all
set "safeSet=set^ "
call %%safeSet%% "var=123"
As now a file named "set<space>.bat" breaks the code.
Re: call set bug?
Posted: 21 Nov 2015 04:53
by Sponge Belly
Hi Jeb,
Ah, now I get it!
The weird syntax is to guard against the unlikely event that a user has a file called "set.bat" or "set<Space>.bat" on his/her PATH.
However did you think to check for that?
And one last thing, you said:
I reinvent the wheel this year, but this time my new technic was a bit more complex.
Which technique are you referring to?
Cheers!
- SB
Re: call set bug?
Posted: 21 Nov 2015 09:57
by jeb
Sponge Belly wrote:Which technique are you referring to?
Ah, sorry I forgot to show it
Code: Select all
(SET LF=^
%EMPTY_LINE%
)
set var=orig
set "SAFESET=^^!LF!!LF!set"
call %%SAFESET%% "var=hello"
set var
And btw I retested the old solution and it fails!
Code: Select all
set "safeSet=set^ ""
call %%safeSet%% var=123"
When a file named "set<space><space>var=123.bat" exists it tries to start it
I suppose my new solution seaches for a file named "<linefeed>set.bat", but that should be more or less safe, as this a uncommon name
Or perhaps a file named "" (empty) is searched ...
Re: call set bug?
Posted: 22 Nov 2015 11:01
by Sponge Belly
Hi Jeb,
Thanks for the explanation, but I think I’ll stick with Dave Benham’s
icall macro if I ever find myself in a situation where I’m forced to make extensive use of call set.
Cheers!
- SB
Re: call set bug?
Posted: 23 Nov 2015 05:03
by trebor68
I have the code from the first Postin changed somewhat.
Code: Select all
@echo off
setlocal enableextensions disabledelayedexpansion
set ^"str= hello ^&^"^& world! ^"
echo CALL ^&^& echo(success ^|^| echo(failure
call && echo(success || echo(failure
echo.
echo.
echo (CALL) ^&^& echo(success ^|^| echo(failure
(call) && echo(success || echo(failure
echo.
echo.
echo (CALL;) ^&^& echo(success ^|^| echo(failure
(call;) && echo(success || echo(failure
echo.
echo.
echo CALL set "str1=%%%%str%%%%" ^&^& echo(success ^|^| echo(failure
call set "str1=%%str%%" && echo(success || echo(failure
echo.
echo.
echo call (SET "str1=%%%%str%%%%" ^&^& echo(success ^|^| echo(failure
call (set "str1=%%str%%" && echo(success || echo(failure
echo.
set str
endlocal & goto :eof
Here the output:
Code: Select all
D:\CMDVerz>test66
CALL && echo(success || echo(failure
success
(CALL) && echo(success || echo(failure
failure
(CALL;) && echo(success || echo(failure
success
CALL set "str1=%%str%%" && echo(success || echo(failure
success
call (SET "str1=%%str%%" && echo(success || echo(failure
failure
str= hello &"& world!
D:\CMDVerz>
The first command to the CALL command follows another character (space). The CALL command is executed correctly.
In the second command the CALL command follows no other sign. The CALL command can not be executed correctly.
The third command the CALL command follows another character (semicolon). The CALL command is executed correctly.
The fourth command the CALL command follows a complete command. The CALL command is executed correctly.
The fifth command the
CALL command
follows an open parenthesis. Everything what comes after the opening parenthesis is running as an independent command (
SET command). The
SET command is not correctly carried out (reason: Number of quotes).