bat
基础:
@title 设置标题
@color 设置颜色
@mode con: cols=50 lines=8 设置行列
@pause 执行完毕暂停
所有bat都应该使用REM注释
REM 是明确的注释,::注释在某些情况下会出错,可能执行时被误当做磁盘访问。::实际上也只是一个不生效的特殊标签,有解析错误的概率,正常情况下在批处理脚本中和rem命令等效,它后面的内容在执行时不显示,也不起任何作用.
echo 中 文为“反馈”、“回显”的意思。它其实是一个开关命令,就是说它只有两种状态:打开和关闭。于是就有了echo on和echo off两个命令了。直接执行echo命令将显示当前echo命令状态(off或on)执行echo off将关闭回显,它后面的所有命令都不显示命令本身,只显示执行后的结果,除非执行echo on命令。首行的@命令和echo off命令联合起来,达到了两个目的:不显示echo off命令本身,不显示以后各行中的命令本身。
bat文件中一个命令过长需要换行时刻在命令中加入^,然后就可以回车换行了.
函数调用:
从批处理程序调用另一个批处理程序(过程)。
CALL [drive:][path]filename [batch-parameters]
batch-parameters 指定批处理程序所需的命令行信息。
如果命令扩展被启用,CALL 会如下改变:
CALL 命令现在将卷标当作 CALL 的目标接受。语法是:
CALL:label arguments
批处理中调用存在调用栈上限,超过上限会溢出报错。(bat栈上限)
参数:
Bat 参数去引号(各种去引号的奇葩方式,三种变量互转),普通变量不能直接去掉外层引号
Windows中的命令行(bat)提示符里的Start命令执行路径包含空格时的问题
START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED] [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL] [/AFFINITY <hex affinity>] [/WAIT] [/B] [command/program] [parameters]
"title" 在窗口标题栏中显示的标题。
由帮助可以看出,Start命令会将第一个带双引号的参数当做标题,因而(start "C:\Program Files\Internet Explorer\iexplore.exe")将会出错. 所以应该在前面加上一对双引号作为标题. 即 start "" "C:\Program Files\Internet Explorer\iexplore.exe"
start /wait calc.exe (等待调用程序结束的启动方式)
@的作用就是让脚本在执行时不显示后面的echo off部分。
find 与linux的netstat | grep "7626"相似 netstat | find "7626"
判断文件是否存在
IF EXIST filename. (
del filename.
) ELSE (
echo filename. missing.
)
路径操作:
取当前路径
在批处理开头加入cd /d %~dp0 一行代码就可以做到“编写一次,到处运行”。%0是批处理文件本身的路径,%~dp进行扩展, d向前扩展到驱动器,p往后扩展到路径。例如,你的bat文件在e:/mybat/test.bat,则%0就是e:/mybat/test.bat, %~dp0是e:/mybat/。
另外,%i提取第i个命令选项,例如%1提取第1个option,i可以取值从1到9
%~0: 取文件名(名+扩展名)
%~f0:取全路径
%~d0:取驱动器名
%~p0:只取路径(不包驱动器)
%~n0:只取文件名
%~x0:只取文件扩展名
%~s0:取缩写全路径名
%~a0:取文件属性
%~t0:取文件创建时间
%~z0:取文件大小
以上选项可以组合起来使用。
取执行路径
%CD%\某程序
取上层路径
@echo off
pushd "%cd%"
cd ..
set pard=%cd%
popd
echo 上一层目录为%pard%
echo 当前目录为%cd%
pause
字符串操作:
替换字符串
%var:str1=str2%
会扩展 var 环境变量,用 "str2" 代替扩展结果中的每个 "str1"。
要有效地从扩展结果中删除所有的 "str1","str2" 可以是空的。
"str1" 可以以星号打头;在这种情况下,"str1" 会从扩展结果的开始到 str1 剩余部分第一次出现的地方,都一直保持相配。
截取字符串
@echo off
set ifo=abcdefghijklmnopqrstuvwxyz0123456789
echo 原字符串(第二行为各字符的序号):
echo %ifo%
echo 123456789012345678901234567890123456
echo 截取前5个字符:
echo %ifo:~0,5%
echo 截取最后5个字符:
echo %ifo:~-5%
echo 截取第一个到倒数第6个字符:
echo %ifo:~0,-5%
echo 从第4个字符开始,截取5个字符:
echo %ifo:~3,5%
echo 从倒数第14个字符开始,截取5个字符:
echo %ifo:~-14,5%
echo 当前时间是:%time% 即 %time:~0,2%点%time:~3,2%分%time:~6,2%秒%time:~9,2%厘秒
pause
扩充字符串
“扩充”这个词汇来自于微软自己的翻译,意思就是对表示文件路径的字符串进行特殊的处理,具体功能罗列如下:
=========================================
~I - 删除任何引号("),扩充 %I
%~fI - 将 %I 扩充到一个完全合格的路径名
%~dI - 仅将 %I 扩充到一个驱动器号
%~pI - 仅将 %I 扩充到一个路径
%~nI - 仅将 %I 扩充到一个文件名
%~xI - 仅将 %I 扩充到一个文件扩展名
%~sI - 扩充的路径只含有短名
%~aI - 将 %I 扩充到文件的文件属性
%~tI - 将 %I 扩充到文件的日期/时间
%~zI - 将 %I 扩充到文件的大小
%~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个完全合格的名称。如果环境变量名
未被定义,或者没有找到文件,此组合键会扩充到
空字符串
可以组合修饰符来得到多重结果:
%~dpI - 仅将 %I 扩充到一个驱动器号和路径
%~nxI - 仅将 %I 扩充到一个文件名和扩展名
%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩充到类似输出线路的 DIR
=========================================
以上内容引用于for /?帮助信息。其中的I代表变量I,不过需要说明的是,不是所有的变量都能够进行扩充的,有两个条件:1、该字符串代表一个文件路径;2、变量要用%x来表示,x可取a-z A-Z 0-9共62个字符中的任意一个。(比如批处理或函数的参数,%0~%9,%x中x取a-z A-Z的形式,for语句里面的变量就是用%x来表示的)
bat标准结束
echo 输出完毕,按任意键退出&&pause>nul&&exit
调试
加一个set打印就好
goto:eof
call和goto:eof call经常和:eof配合,这个是个默认标签,在调用了call跳转到一个标签之后倘若想再跳回去则必须用goto:eof
set /A 不支持后面数字出现08 和 09 是无效的数字,因为 8 和 9 不是有效的八进制位数
此时支持数字格式为:十六进制有 0x 前缀,八进制有 0 前缀的,数字值为十进位数字。而08、09就成了八进制,但又会是非法8进制
技巧操作:
setlocal 和 endlocal
setlocal 和 endlocal 之间对于变量的所有修改对外部不可见
1.这可以相当于其他语言中的作用域,新定义的变量只有在作用域内存在,作用域外不存在;
2.但是对于全局变量(外层作用域变量)的操作则有所不同,作用域中可以访问全局变量(外层作用域变量),但是对于全局变量(外层作用域变量)的修改,只在作用域内生效,在作用域外是不生效的。可以将对于全局变量的修改理解为作用域内重新定义,这样在作用域内相当于覆盖了全局变量定义。
3.这种作用域是允许嵌套的,不过嵌套层数限制为最多32层,否则就会提示 “以达到最大递归层”的错误信息。
4.有了作用域后,批处理的函数便更像其他语言的函数,因为拥有了局部变量。
5.然后带来的问题则是使用作用域之后,作用域内部变量如何返回出去呢,下面两种方式:
①
{
endlocal
REM 这里必须使用%%,为了在执行这一段之前使用作用域内部变量替换指令,然后退出作用域执行指令
set globalval=%innerval%
}
②
endlocal & set globalval=%innerval%
bat函数管道读取
while read line do … done