为什么批处理文件切换当前目录的命令提示符不能使用SETLOCAL命令?

时间:2017-05-24 04:34:23

标签: batch-file cmd

我在命令提示符窗口中运行以下批处理脚本以转到特定文件夹。

@echo off
SETLOCAL

set ispyfolder=true
if not "%~1"=="py" if not "%~1"=="pyfolder" set ispyfolder=false
if "%ispyfolder%"=="true" (
    C:
    cd C:\Users\ankagraw\AppData\Local\Continuum
)

当SETLOCAL存在时(第2行),此代码不起作用。当前目录与在命令提示符窗口中运行批处理文件之前的目录相同。如果我删除这一行,那么脚本工作正常。

我已将脚本命名为go2。所以我想这样称呼它:

go2 pyfolder

我想使用SETLOCAL来避免错误地触及全局环境变量。

我想我犯了一个非常简单的错误。但我不熟悉脚本,因此无法弄明白。

1 个答案:

答案 0 :(得分:3)

您的批处理代码有效。我认为真正的问题是在Windows命令解释器处理批处理文件的其他命令之前在发布块之后使用的 ENDLOCAL 命令。

如果批处理文件在终止批处理文件的执行之前不包含更多命令,则Windows命令解释程序将隐式执行

ENDLOCAL ,这对于了解何时从批处理文件执行批处理文件非常重要。命令提示符窗口和预期的行为是批处理文件应该修改已经运行的命令进程的当前目录。

让我们看一下下面改进的批处理代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "ispyfolder=true"
if /I not "%~1" == "py" if /I not "%~1" == "pyfolder" set "ispyfolder=false"
if not defined LOCALAPPDATA set "LOCALAPPDATA=%USERPROFILE%\AppData\Local"
if "%ispyfolder%" == "true" echo cd /D "%LOCALAPPDATA%\Continuum"

rem Other commands in this local environment like the one below.
echo 1: Current directory is: %CD%

endlocal
rem Commands executed in previous environment with previous current directory.
echo 2: Current directory is: %CD%

Why is no string output with 'echo %var%' after using 'set var = text' on command line?

上的答案解释了使用两次set "variable=value"的原因

通过使用命令 IF 的两次选项/I,在此改进的代码中,对第一个批处理文件参数的两个字符串比较不区分大小写。

LOCALAPPDATA 是预定义的Windows environment variable,因为Windows Vista引入了本地应用程序数据目录。在Windows XP上,默认情况下没有本地应用程序数据目录,因此也没有 LOCALAPPDATA 环境变量。但是,我添加了一行来在本地环境中定义此环境变量,以防未定义,这在您的计算机上很可能是不必要的。

命令 CD 也可以选择/D来更改驱动器

有关命令 SETLOCAL ENDLOCAL 的详细信息,请阅读this answer

然后在命令提示符窗口中以C:\Users\ankagraw作为当前目录运行此批处理文件,其中pypyfolder作为第一个参数。你得到了输出:

1: Current directory is: C:\Users\ankagraw\AppData\Local\Continuum
2: Current directory is: C:\Users\ankagraw

这里可以看到命令 ENDLOCAL 也恢复当前目录。这可能是您的批处理文件的问题,命令行低于endlocal,或者执行从命令提示符窗口中发布的批处理文件。

解决方案是通过以下行替换命令行endlocal,或者如果批处理文件不包含任何其他内容,则添加此命令行。

endlocal & cd /D "%CD%"

在执行第一个命令 ENDLOCAL 之前,Windows命令解释程序使用当前值扩展环境变量 CD 。因此,在您的计算机上执行了批处理文件,参数为pypyfolder命令行:

endlocal & cd /D "C:\Users\ankagraw\AppData\Local\Continuum"

ENDLOCAL 删除本地环境变量表并恢复以前的环境变量表,恢复命令扩展和延迟扩展的状态,并恢复上一个当前目录。但是执行下一个命令 CD ,将当前目录再次更改为之前命令环境中的目录。

所以我建议你在电脑上使用:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ispyfolder=true"
if /I not "%~1" == "py" if /I not "%~1" == "pyfolder" set "ispyfolder=false"
if "%ispyfolder%" == "true" echo cd /D "%LOCALAPPDATA%\Continuum"
endlocal & cd /D "%CD%"

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • cd /?
  • echo /?
  • endlocal /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?