批处理文件中的嵌套If Exist语句

5

好的,我正在尝试编写一些嵌套的IF EXIST语句来检查一些文件夹是否存在。如果第一个文件夹存在,则将Folder1设置为1,然后跳过到Install。Folder2也是同样的方式,如果两个文件夹都不存在,则直接跳过到Install。

但是即使Folder1不存在,它仍会将%Folder1%设置为1。我错过了什么/没做什么吗?

谢谢!

if exist "c:\folder1" set Folder1=1
    echo %Folder1%
    goto install
else if exist "c:\folder2" set Folder2=1
    echo %Folder2%
    goto Install
else goto Install   

:Install
3个回答

11

两个基本问题:

1. 复合语句必须用括号括起来。

2. 在括号内更改变量的值将不可见,除非您已执行SETLOCAL ENABLEDELAYEDEXPANSION - 即使这样,您仍需要使用!var!而不是%var%。

因此:

SETLOCAL ENABLEDELAYEDEXPANSION
if exist "c:\folder1" (
        set Folder1=1
        echo !Folder1!
        goto install
) else if exist "c:\folder2" (
        set Folder2=1
        echo !Folder2!
        goto Install
) else goto Install 

:Install

最好的情况是,

@ECHO off
if exist "c:\folder1" (
        set Folder1=1
        goto install
) else if exist "c:\folder2" (
        set Folder2=1
        goto Install
) else goto Install 

:Install

SET folder

甚至更简单
@ECHO off
if exist "c:\folder1" set Folder1=1&goto install
if exist "c:\folder2" set Folder2=1&goto Install
:Install

SET folder

测试:

@ECHO OFF
setlocal
SET "folder1="
SET "folder2="
ECHO.----------No folders
DIR /b /ad c:\folder*
CALL :test
ECHO.----------Folder 1 only
MD c:\folder1
DIR /b /ad c:\folder*
CALL :test
ECHO.----------Folder 2 only
RD c:\folder1
MD c:\folder2
DIR /b /ad c:\folder*
CALL :test
ECHO.----------Both
MD c:\folder1
DIR /b /ad c:\folder*
CALL :test
RD c:\folder1
RD c:\folder2

GOTO :eof

:test
if exist "c:\folder1" set Folder1=1&goto install
if exist "c:\folder2" set Folder2=1&goto Install
:Install

SET folder
SET "folder1="
SET "folder2="
GOTO :eof

这个测试创建并删除了两个相关的目录。

以下是结果:

----------No folders
----------Folder 1 only
folder1
Folder1=1
----------Folder 2 only
folder2
Folder2=1
----------Both
folder1
folder2
Folder1=1

请提供需要翻译的内容。
    SET "folder1="
    SET "folder2="

该函数在每次报告生成前和启动时均会执行,以确保将涉及的环境变量从环境中删除,以防止代码基于过期信息而产生错误结果。


这个评论系统太糟糕了(除非我不知道如何使用这个评论系统)。Peter,我尝试了你的简单解决方案,但即使C:\ Folder1不存在,它也总是将Folder1设置为等于1。 - Brian
很有可能这些变量是由之前的运行设置的。必须明确地将变量设置为“nothing”才能将其从环境中删除。这就是为什么大多数批处理程序在@echo off之后立即使用SETLOCAL的原因。通过setlocal,任何环境更改都会在例程结束时撤消。 - Magoo
好的,我之前没有执行SET“folder1 =”将其清零,也没有执行SETLOCAL。所以可能我在使用旧数据。让我再试一次。 - Brian
好的,这似乎很好用...而且更干净(尽管Endoro的也可以(谢谢))。但是我需要同时使用SETLOCAL和SET "folderX="命令吗?据我所知,它们都做同样的事情?或者最好在其中两个都有? - Brian
没有硬性规定。程序开始时的 SETLOCAL 确保批处理完成时环境不会改变。可能整个程序的重点就是设置一些环境变量。另一方面,您在程序中使用的变量并不能保证没有被其他方式设置 - 例如之前运行批处理时未使用 SETLOCAL 或者用户从提示符输入 SET var=whatever 指令。批处理不知道,所以 set "var=" 确保了这一点。 - Magoo
明白了...这就是我认为你可能意思的。只是一种安全措施。谢谢! - Brian

1
if exist "c:\folder1" (
        set Folder1=1
        echo %Folder1%
        goto install
) if exist "c:\folder2" (
        set Folder2=1
        echo %Folder2%
        goto Install
) else goto Install 

:Install

0
这段代码如果folder1不存在,则不会设置%folder1%=1,并且在这种情况下不会产生任何输出。如果Folder1不存在并且Folder2存在%folder2%将被设置为1,否则%folder2%为空。如果一个变量为空,请在echo命令后放置一个未关闭的左括号以抑制输出。
@echo off &setlocal
if exist "c:\folder1" set "Folder1=1"
echo(%Folder1%
if not defined Folder1 if exist "c:\folder2" set "Folder2=1"
echo(%Folder2%
goto Install

:Install
endlocal

这个解决方案似乎可行,尽管更加复杂/代码化。我需要进行更多的测试,但看起来这将适用于Folder1存在、Folder2存在或两者都不存在的情况。 - Brian
这个类似于 else,只有在 folder1 不存在的情况下才测试 folder2。 - Endoro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接