上一篇文章分享了Bat批处理的部分基础知识,包括echo、@、pause命令、批处理注释、重定向符号、批处理文件参数,今天继续分享Bat批处理的基础知识errorlevel、setlocal/endlocal 命令、shift 命令、获取磁盘路径 %~dp0。
1
errorlevel 基础用法
errorlevel 用来判断上条命令的返回值,在 if ? 语句的帮助文档中有说明,如下图:

if errorlevel number command,意思是:如果返回的错误码值大于或等于number值的时候,则执行cmmand 操作。
实例:
@echo off
coyp 1.txt bak/2.txt
echo errorlevel=%errorlevel%
if errorlevel 0 echo SUCCESS
pause
运行结果:

可以看到errolevel=9009,errolevel的值大于0,所以输出了SUCCESS;将if errorlevel 0 echo SUCCESS中的0改为9010,结果如下图:

没有输出SUCCESS,因为errolevel的值小于9010,所以没有执行echo SUCCESS。
还有另外一种句式,if %errorlevel%==值 cmmand ,意思是:如果返回的错误码值等于值的时候,将执行cmmand操作。
实例:
@echo off
coyp 1.txt bak/2.txt
echo errorlevel=%errorlevel%
if %errorlevel%==0 (
echo success
) else (
echo error
)
pause
运行结果:

if %errorlevel%==0是判断errorlevel是否等于0,因为errolevel的值等于9009,所以执行了echo error,当把命令改成if %errorlevel%==9009时,输出了success。
一般情况下,一条命令的执行结果返回的值只有两个:“成功”用 0 表示;“失败”用 1 表示;实际上,errorlevel 返回值可以在0~255 之间,例如 xcopy 默认的errorlevel 值有5 个,分别表示5 种执行状态:
0 表示复制文件成功
1 没有找到复制文件
2 通过CTRL + C 终止了xcopy操作
4 初始化错误
5 磁盘写入错误
if %ERRORLEVEL% 对数值的比较方法不仅仅限于等于,还可以使用参数来控制。
比较参数如下:
EQU ——等于
NEQ ——不等于
LSS —— 小于
LEQ —— 小于或等于
GTR —— 大于
GEQ —— 大于或等于
2
setlocal/endlocal 命令
setlocal 和 endlocal 命令是用来定义一个局部区域,这个局部区域中的环境变量任何变化都不会改变原先的环境变量。
在执行 setlocal 之后所做的环境改动只限于批处理文件,要还原原先的设置,必须执行 endlocal ,达到批处理文件结尾时,对于该批处理文件的每个尚未执行的 setlocal 命令,都会有一个隐含的 endlocal 被执行。
无论在 setlocal 命令之前它们的设置是什么,这些修改会一直保留到匹配的 endlocal 命令。
endlocal结束批处理文件中环境改动的本地化操作,在执行 endlocal 之后所做的环境改动不再仅限于批处理文件,批处理文件结束后,原先的设置无法还原。
实例:
@echo off
set test=“ABC” &::设置test的变量值为“ABC”
echo setlocal定义区域之前:
set test
pause
setlocal &::开始定义局部区域
set test=“DEF” &::设置test的变量值为“DEF”
echo setlocal定义局部区域并设置test的值为“DEF”
set test
pause
endlocal &::结束局部区域
echo endlocal之后结束局部区域,test值恢复最初值
set test
pause
运行结果:

在setlocal定义的局部区域,设置了test=“DEF”,当通过endlocal结束定义的局部区域后,test的值恢复成最开始设置的“ABC”。
3
shift 命令
shift 命令用于更改批处理文件处理参数的方式,如指定起始处理参数的位置等。

实例:利用 shift 命令动态输出批处理执行时输入的所有参数。
@echo off
:round
if "%1"=="" goto cmd1
echo 参数:%1
shift
goto round
:cmd1
echo 没有获取到参数,结束脚本
goto end
:end
运行结果:

实例:使用 shift n 的方式重新设置处理参数的起止位置。
@echo off
echo 参数1:%1
echo 参数2:%2
运行结果:

运行上面实例,传递了5个参数,分别是:A1 B2 C3 D5 E6
在执行 echo 之前添加 “shift 2” 命令,cmd.exe 将把传递参数的起始位置设置为2,即 %3 移动到 %2。代码如下:
@echo off
shift /2
echo 参数1:%1
echo 参数2:%2
运行结果:

4
获取磁盘路径 %~dp0
%cd% 或者 %~dp0 用来获取当前目录路径。
%cd%
%cd% 扩展到当前目录字符串。需要注意的是,这里的当前目录有可能和脚本实际所在目录不一致。实例:
@echo off
set BPath=%cd%
echo %BPath%
pause
运行结果:

%cd% 返回的是当前执行环境目录。
%~dp0
%~dp0 可以用来获取批处理文件的实际路径,与当前 DOS 环境所在的目录没有关系。其中:
%~dp0 的 “d” 为 Drive 的缩写,即为驱动器,磁盘;
%~dp0 的 “p” 为 Path 缩写,即为路径,目录;
可以使用 cd 命令转到 %~dp0 返回的目录,不过推荐使用 cd d %~dp0。
实例:获取批处理文件自身磁盘路径。
@echo off
set BPath=%~dp0
echo %BPath%
pause
把1.bat文件放到D盘,运行结果:

更多选项语法:
~0 删除任何引号("),扩充 %0
%~d0 仅将 %0 扩充到一个驱动器号
%~f0 将 %0 扩充到一个完全合格的路径名(“f”是 file,即文件)
%~p0 仅将 %0 扩充到一个路径
%~n0 仅将 %0 扩充到一个文件名(“n” 是 name 文件名)
%~x0 仅将 %0 扩充到一个文件扩展名
%~s0 扩充的路径只含有短名(“s” 为 Short,短的)
%~a0 将 %0 扩充到文件的文件属性(“a” 为 attribute,即属性)
%~t0 将 %0 扩充到文件的日期/时间(“t” time)
%~z0 将 %0 扩充到文件的大小(Size 大小)
%~$PATH:0 查找列在路径环境变量的目录,并将 %0 扩充到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此组合键会扩充到空字符串。
实例:查看每个选项的输出结果。
@echo off
REM C:
echo %~d0
REM C:\Users\Administrator\Desktop\1.bat
echo %~f0
REM \Users\Administrator\Desktop\
echo %~p0
REM 1
echo %~n0
REM .bat
echo %~x0
REM C:\Users\Administrator\Desktop\1.bat
echo %~s0
REM --a------
echo %~a0
REM 2023/04/16 20:17
echo %~t0
REM 337
echo %~z0
pause
运行结果:

可以组合修饰符来得到多重结果:
%~dp0 仅将 %0 扩充到一个驱动器号和路径
%~nx0 仅将 %0 扩充到一个文件名和扩展名
%~fs0 仅将 %0 扩充到一个带有短名的完整路径名
%~dp$PATH:0 查找列在路径环境变量的目录,并将 %I 扩充到找到的第一个驱动器号和路径。
%~ftza0 将 %0 扩充到类似输出线路的 DIR
%0 为当前批处理文件。如果0换成1为第一个文件,2为第2个。
@echo off
REM C:\Users\Administrator\Desktop\
echo %~dp0
REM 1.bat
echo %~nx0
REM C:\Users\Administrator\Desktop\1.bat
echo %~fs0
REM C:\Users\Administrator\Desktop\
echo %~dp$PATH:0
REM --a-------- 2023/04/16 20:30 258 C:\Users\Administrator\Desktop\1.bat
echo %~ftza0
REM C:\Users\Administrator\Desktop\1.bat
echo %~0
pause
运行结果:

%cd% 和 %~dp0 均可以获取到当前路径, %~dp0 获取的是批处理文件所在目录的路径,%cd% 获取的是当前 DOS 环境的路径。如果批处理文件和执行批处理文件不再同一目录,则 %cd% 返回的路径并不是批处理文件所在目录的路径,而是执行环境当前的路径。
%cd% 和 %~dp0 区别:
①使用范围上的不同
%cd% 可以在批处理脚本(bat脚本)、命令行窗口中使用;
%~dp0 只能在批处理脚本(bat脚本) 中使用;
②bat 脚本执行时,%cd% 代表的值会变化,因为代表的是当前目录;
%~dp0 代表的值不会变化,因为代表的是脚本文件在磁盘的位置。




