Why does a batch file switching current directory for command prompt not work on using SETLOCAL command?

后端 未结 1 1344
暗喜
暗喜 2021-01-24 02:35

I am running the following batch script from within a command prompt window to go to a specific folder.

@echo off
SETLOCAL

set ispyfolder=true
if not \"%~1\"==\         


        
相关标签:
1条回答
  • 2021-01-24 03:33

    Your batch code works. I think the real problem is the ENDLOCAL command used after the posted block before the other commands of the batch file are processed by Windows command interpreter.

    ENDLOCAL is executed implicitly by Windows command interpreter in case of the batch file does not contain more commands before terminating execution of the batch file which is important to know when the batch file is executed from within a command prompt window and the expected behavior is that the current directory of the already running command process should be modified by the batch file.

    Let us look on the improved batch code below:

    @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%
    

    The reason for using twice set "variable=value" is explained by answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line?

    The two string comparisons with first batch file argument are made case-insensitive in this improved code by using twice option /I of command IF.

    LOCALAPPDATA is a predefined Windows environment variable since Windows Vista introducing the local application data directory. On Windows XP there is by default no local application data directory and therefore also no LOCALAPPDATA environment variable. However, I added a line to define this environment variable in local environment in case of not being defined which is most likely not necessary on your computer.

    The command CD has the option /D to change drive, too.

    Read this answer for details about the commands SETLOCAL and ENDLOCAL.

    Then run this batch file from within a command prompt window with C:\Users\ankagraw as current directory with py or pyfolder as first parameter. You get the output:

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

    It can be seen here that the command ENDLOCAL restores also the current directory. And this might be your problem with your batch file with command lines below endlocal or on executing the batch file as posted from within a command prompt window.

    The solution is replacing the command line endlocal by the line below or adding this command line if the batch file does not contain anything else.

    endlocal & cd /D "%CD%"
    

    The environment variable CD is expanded here by Windows command interpreter using the current value of it before executing the first command ENDLOCAL. So executed is on your computer with batch file started with parameter being py or pyfolder the command line:

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

    ENDLOCAL deletes the local environment variables table and restores the previous environment variables table, restores the states for command extensions and delayed expansion and restores also the previous current directory. But next command CD is executed to change the current directory once again to the directory as it was before in previous command environment.

    So I suggest to use on your computer:

    @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%"
    

    For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

    • cd /?
    • echo /?
    • endlocal /?
    • if /?
    • rem /?
    • set /?
    • setlocal /?
    0 讨论(0)
提交回复
热议问题