批处理脚本if exist检测文件存在,fc命令却提示文件不存在
问题原因与解决方法
核心原因
从报错信息能看到,fc命令尝试访问的是大写路径./SNAPSHOTS/*filename*.TXT,但脚本里用的是小写路径./snapshots/!filename!.txt。虽然Windows文件系统默认不区分大小写,但像fc这类命令在路径大小写不匹配时,可能出现解析异常;另外批处理原生更适配反斜杠\作为路径分隔符,用斜杠/也可能导致部分命令解析出错。
解决方法
方法1:统一路径大小写与分隔符
把脚本中所有路径的大小写改成和实际文件/文件夹一致的格式,同时将斜杠/替换为批处理支持的反斜杠\:
@echo off setlocal enabledelayedexpansion set passed=0 set failed=0 set nosnaps=0 for %%i in (.\tests\*) do ( set "filename=%%~ni" dune exec ..\_build\default\bin\main.exe .\tests\%%i > ".\results\!filename!.txt" 2> nul if exist ".\snapshots\!filename!.txt" ( fc ".\snapshots\!filename!.txt" ".\results\!filename!.txt" > nul if !errorlevel! == 0 ( echo PASSED TEST: !filename! set /a passed+=1 ) else ( echo FAILED TEST: !filename! set /a failed+=1 ) ) else ( echo NOSNAP TEST: !filename! set /a nosnaps+=1 ) ) echo -------- echo PASSED: !passed! echo FAILED: !failed! echo NOSNAP: !nosnaps! endlocal
注意:如果系统里实际的文件夹是大写
SNAPSHOTS,就把路径里的snapshots改成SNAPSHOTS,确保和实际名称完全一致。
方法2:用绝对路径规避解析歧义
先获取脚本所在的绝对目录,再拼接成完整的文件路径,彻底解决相对路径的解析问题:
@echo off setlocal enabledelayedexpansion set "script_dir=%~dp0" set passed=0 set failed=0 set nosnaps=0 for %%i in ("%script_dir%tests\*") do ( set "filename=%%~ni" dune exec "%script_dir%..\_build\default\bin\main.exe" "%%i" > "%script_dir%results\!filename!.txt" 2> nul set "snap_file=%script_dir%snapshots\!filename!.txt" if exist "!snap_file!" ( fc "!snap_file!" "%script_dir%results\!filename!.txt" > nul if !errorlevel! == 0 ( echo PASSED TEST: !filename! set /a passed+=1 ) else ( echo FAILED TEST: !filename! set /a failed+=1 ) ) else ( echo NOSNAP TEST: !filename! set /a nosnaps+=1 ) ) echo -------- echo PASSED: !passed! echo FAILED: !failed! echo NOSNAP: !nosnaps! endlocal
这个方法通过%~dp0拿到脚本所在的绝对目录,所有文件路径都基于此目录拼接,避免了不同执行环境下相对路径的解析偏差。
方法3:排查文件名特殊字符
如果!filename!包含空格、&、%这类特殊字符,要确保路径被双引号包裹(你的脚本已经做了这一步,可再确认)。要是特殊字符导致解析问题,可在set "filename=%%~ni"之后添加转义处理,不过多数情况下双引号包裹路径就能解决。
内容的提问来源于stack exchange,提问作者Handsome guy
相关产品推荐
相关产品推荐

