为什么我的cd%myVar%被忽略了?

时间:2015-11-02 18:03:24

标签: batch-file

我将原始路径保存在originalPath中,然后移至另一个文件夹。最后,当我cd %originalPath%时,它不起作用。它停留在新的道路上。

我尝试过使用pushd %myPath%popd,但它也不起作用。

C:\BatchTests\包含我的脚本和文件夹Subfolder1

我的剧本:

@echo off
set myPath=Subfolder1
set folderList=input.txt
REM set originalPath=%CD%
set originalPath=%~dp0  

REM pushd %myPath%
cd %myPath%
setlocal EnableDelayedExpansion

:process

REM The rest of my script

echo %originalPath%
REM echo %originalPath% prints: C:\BatchTests\
cd %originalPath%
REM popd
pause

为什么会这样?

2 个答案:

答案 0 :(得分:2)

实际上它并没有真正留在更改的目录中。真正的问题是setlocal除了环境变量更改外,还缓存了您已经cd %myPath%更改过的当前目录。

然后您通过cd %originalPath%切换回以前的目录。但是,只要批处理脚本完成执行,就会发生隐式endlocal,将当前目录重置为setlocal之前缓存的目录。

如果您从REMpushd行中删除popd并注释掉cd行,则问题完全相同。

要解决此问题,只需将cd %myPath%行(或pushd命令)向下移至setlocal以下即可。实际上,当您仅在setlocal / endlocal块之间进行更改时,您甚至不需要最初存储当前目录(即使未明确说明endlocal):

@echo off
set myPath=Subfolder1
set folderList=input.txt

setlocal EnableDelayedExpansion
REM pushd %myPath%
cd %myPath%

:process

REM The rest of my script

REM popd
pause
endlocal

答案 1 :(得分:2)

1。引用未知路径

运行批处理文件时未知的路径未被修复可能包含1个或多个空格。这意味着路径字符串应该像文件名一样引用。

2。更改驱动器和目录

命令 CD 默认情况下仅更改当前驱动器上的当前目录。

当启动批处理文件的当前目录未在临时使用的当前目录所在的驱动器上修复时,应始终使用选项/D将当前目录更改为任何带字母的驱动器上的目录。

3。 setlocal和endlocal保存并恢复当前目录

命令 setlocal 始终会创建环境表的新副本,该副本在使用 endlocal 或退出恢复上一个表的批处理文件时会被销毁。此外,还会保存和恢复命令扩展和延迟扩展的状态。请参阅this answer,并举例说明使用 setlocal endlocal 会发生什么。

此外 setlocal 还会保存当前目录,而 endlocal 会将其还原,如下面的代码所示。

@echo off
set "InitialPath=%CD%"
echo 1. Current directory is: %CD%
cd /D "%windir%\Temp"
echo 2. Current directory is: %CD%
setlocal
rem Change current directory to parent directory.
cd ..\
echo 3. Current directory is: %CD%
setlocal
rem Change current directory to root of current drive.
cd \
echo 4. Current directory is: %CD%
endlocal
echo 5. Current directory is: %CD%
endlocal
echo 6. Current directory is: %CD%
cd /D "%InitialPath%"
echo 7. Current directory is: %CD%
set "InitialPath="
pause

4。分配给环境变量的尾随空格和制表符

在为环境变量赋值时没有使用双引号,命令 set 会将首次等号后的所有内容追加到环境变量的行尾,包括不可见的尾随空格和制表符。 set originalPath=%~dp0  行上有尾随空格,有关详细信息,请参阅Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案。

您的代码已得到改进,以避免上面列出的所有问题:

@echo off
set "myPath=Subfolder1"
set "folderList=input.txt"
REM set "originalPath=%CD%"
set "originalPath=%~dp0"

REM pushd "%myPath%"
cd /D "%myPath%"
setlocal EnableDelayedExpansion

:process
REM The rest of my script

endlocal
echo %originalPath%
REM echo %originalPath% prints: C:\BatchTests\
cd /D "%originalPath%"
REM popd
pause

考虑到第3点,并且aschipfl也解释得很好,以下也可以。

@echo off
set "myPath=Subfolder1"
set "folderList=input.txt"

setlocal EnableDelayedExpansion
cd /D "%myPath%"

:process
REM The rest of my script

endlocal
pause