1

Something rather odd happening with the parentheses for this code:

Setlocal EnableDelayedExpansion
MyFOLDER=
FOR %%B IN (c,d,e,f,g) DO (@%%B: 2>nul && set z=%%B <nul if exist %z%\
(if %MYFOLDER%==[] (echo %z%
)
)
)

The above compiles, but this doesn't:

Setlocal EnableDelayedExpansion
MyFOLDER=
FOR %%B IN (c,d,e,f,g) DO (@%%B: 2>nul && set z=%%B <nul if exist %z%\
(if %MYFOLDER%==[] (
echo %z%
)
)
)

Nor this

Setlocal EnableDelayedExpansion
MyFOLDER=
FOR %%B IN (c,d,e,f,g) DO (@%%B: 2>nul && set z=%%B <nul if exist %z%\
(if %MYFOLDER%==[]
(
echo %z%
)
)
)

nor any other combination where "echo %z%" is below the (if MYFOLDER) line. Is there anything in the "FOR" line that is suspect?

4
  • 2
    Batch files are not compiled. Are you getting an error when you try to run these?
    – aphoria
    Commented Nov 18, 2014 at 13:29
  • 1
    What is this script supposed to accomplish?
    – mojo
    Commented Nov 18, 2014 at 13:42
  • Is assembled better? Fixed the %MYFOLDER%, thanks. How do I trap the error? The window just closes. Commented Nov 19, 2014 at 5:28
  • 1
    Much better to use PowerShell. Commented Nov 19, 2014 at 21:47

2 Answers 2

6

I see a few problems in spite of having no understanding of the goal.

You define a variable using SET (e.g. SET MyFolder=). In the Unix shells, you just say MyFOLDER=, but not in CMD.

The IF comparison of MYFOLDER (which should be done with == not =) is probably meaningless because you're not doing it in a way that will use the contents of the variable. You're just comparing the literal string MYFOLDER to the literal string []. This comparison will always be false and never change throughout the course of script execution.

You are making an assignment inside parentheses (the entire contents of which are evaluated all at once, including normal variable substitution) and then attempting to access that variable inside the same "block" (CMD doesn't really have well-defined syntax, but it's at least similar to a block). What will happen is that the %z% will be evaluated the moment the (...) is evaluated and, in this script, it will be empty and replaced with nothing. The subsequent IF EXIST will eat the next thing you give it, which is the parenthetical expression. I'm not able to predict what will really happen there.

I don't know why you're assigning %%B to z and then using z in a comparison. Why not just use %%B? %%B at least will use delayed expansion.

You've enabled Delayed Expansion, but you haven't used it (except for the FOR variable which is always delayed whether you turn on delayed expansion or not). To use delayed expansion, you have to surround the variable with bangs (!) instead of the normal percent (%). So, in the case of z, or MYFOLDER, it would become !z! and !MYFOLDER! respectively. Accessing variables this way is absolutely essential inside a parenthetical "block" if you assign a value to a variable within that same block.

I'd offer a revision of your script, but I'm too dull to understand what you're trying to accomplish.

1
0

This is an updated version of the above codeblock with a description of what is intended. I think it is better to post this as a solution rather than clog up the OP or edit it any further.

The script is supposed to search all NTFS drive candidates for "common\MYFOLDER". If the first occurrence of "common\MYFOLDER" on a drive is located, do stuff with it, and continue the search for the same on other drives. The user is warned of this and can back out to :ENDSCRIPT if desired. The assembler still aborts in a cmd window at "if exist %%B:" with "%%B is unexpected at this time"

Edit: Still bombs out still at the first for I think. How is the error viewed? Is it true that if copied to existing cmd window all the nested "!!"s must be replaced with "!"

Edit2: We get "'else' is not recognized as a internal or external command..." Might it be a problem with the GOTOs?

Edit3: ") else (" is required.

Setlocal EnableDelayedExpansion
set CURRDRIVE=B
SET MYFOLDER=

:SEARCHDRIVES



for %%B in (B C D E F G) do (
if exist %%B: (
%%B:
if NOT DEFINED MYFOLDER (
for /d /r %%c in (*) do (
if /i %%pc==\common\MYFOLDER\ (
set MYFOLDER=%%c GOTO GOTMYFOLDER))
) else (
if !CURRDRIVE!==%%B (
%%B:
for /d /r ... %%c in (*) do (
if /i %%pc===\common\MYFOLDER\ (
set MYFOLDER=%%c
color C4
SET /P deletefiles="There appears to be a duplicate mirrored drive. Do you wish to remove files on this drive as well? N will quit the script. (Y/N)"
echo deletefiles & echo. & echo "While the script runs, this message will appear for every fixed drive {ABCDEFG} detected containing a duplicate MYFOLDER directory."
if /i !deletefiles!==n GOTO FINISH
GOTO GOTMYFOLDER)
)
)
)
)
REM Exist Drive
)
REM Drives Loop



if DEFINED MYFOLDER (
GOTO FINISH
) else (
echo No Nonsense installed on this computer
pause
GOTO ENDSCRIPT)





:GOTMYFOLDER

cd /d %CURRDRIVE%:\
cd %MYFOLDER%

REM DO STUFF WITH MYFOLDER

if %CURRDRIVE%==B (
set CURRDRIVE=C
GOTO SEARCHDRIVES)
if %CURRDRIVE%==C (
set CURRDRIVE=D
GOTO SEARCHDRIVES)
if %CURRDRIVE%==D (
set CURRDRIVE=E
GOTO SEARCHDRIVES)
if %CURRDRIVE%==E (
set CURRDRIVE=F
GOTO SEARCHDRIVES)
if %CURRDRIVE%==F (
set CURRDRIVE=G
GOTO SEARCHDRIVES)

:FINISH
REM BLAH
:ENDSCRIPT
REM BLAH
4
  • 1
    It would be a good idea to read the help pages of the commands. If you want to use a parenthesis after an IF it must be on the same line
    – jeb
    Commented Nov 19, 2014 at 10:40
  • Oops, my bad. (Still in C mode.) The [ss64.com/nt/if.html] did give an example of such but had no explicit rules on parentheses. However in the "For" page it did suggest the use of :subroutine- which may suit the use of nested IFs and FORs in batch a little better. Commented Nov 19, 2014 at 11:22
  • You can't apply delayed expansion to loop variables. !!B (and others like that) won't work. You don't need delayed expansion with them anyway, %%B should work just fine.
    – Andriy M
    Commented Nov 19, 2014 at 21:43
  • Ugh I think i found the bbb (batch beginner bug). So the only time to use bangs is when referencing a non loop variable modified within a parenthetical expression? I guess your observation also applies when referencing new nested loop variables within the said new nested loops? Commented Nov 20, 2014 at 3:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.