我将原始路径保存在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
为什么会这样?
答案 0 :(得分:2)
实际上它并没有真正留在更改的目录中。真正的问题是setlocal
除了环境变量更改外,还缓存了您已经cd %myPath%
更改过的当前目录。
然后您通过cd %originalPath%
切换回以前的目录。但是,只要批处理脚本完成执行,就会发生隐式endlocal
,将当前目录重置为setlocal
之前缓存的目录。
如果您从REM
和pushd
行中删除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个或多个空格。这意味着路径字符串应该像文件名一样引用。
命令 CD 默认情况下仅更改当前驱动器上的当前目录。
当启动批处理文件的当前目录未在临时使用的当前目录所在的驱动器上修复时,应始终使用选项/D
将当前目录更改为任何带字母的驱动器上的目录。
命令 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
在为环境变量赋值时没有使用双引号,命令 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