最近项目须要再 windows 上作开发,并且一些自动化的处理须要使用 windows 的的脚本。因此作些记录,防止遗忘。linux
首先从基础开始吧,以前都是使用 linux bash 的。能够说 windows bat 脚本和 linux bash 脚本仍是有不少区别的。windows
变量设置使用的命令为set
。bash
set a="hello world" echo %a%
从上面的脚本中能够知道,使用set
来设置变量,语法为set var=<值>
。若是要引用这个变量的话就使用%var%
。服务器
注:bat 脚本不能像 bash 中同样设置临时变量,只用将变量设置为环境变量。
set
命令的功能仍是比较强大的,好比获取从键盘中输入的字符:函数
set /p a="Input a number:" echo %a%
支持算术:code
set /a a=1+2 echo %a% set /a a-=1 echo %a% set /a a*=3 echo %a% set /a a/=3 echo %a%
这个关键在于set /a
还有字符串的修改和截取:token
:::::::::: 字符串的截取 :::::::::: set a=Hello Windows Bat :: 截取全部 set a=%a:~0% :: 截取指定的 set a=%a:~1,-1% set a=%a:~2,4% :::::::::: 字符串的替换 :::::::::: set a=Hello Windows :: 将Windows替换成Linux set a=%a:Windows=Linux%
bat 中能实现注释功能的有两个::
和rem
。
它们的不一样点是:rem
是一条命令,在运行的时候至关于把rem自己及其后面的内容置空。既然它是一条命令,就必须处于单独的一行或者有相似 "&" 的链接符号链接。
bat 遇到以冒号 ":" 开头的行时(忽略冒号前的空格),会将其后的语句识别为“标记”而不是命令语句,所以相似 ":label" 这样的在 bat 中仅仅是一个标记。ip
注: 使用 bat 中的注释时须要注意一点,不要再 () 的边上使用注释。
bat 中的条件判断也是使用if
。开发
set a=1 if %a%==1 ( echo OK ) else ( echo ERROR )
若是时判断字符串使用为空时,能够这样处理:rem
set a="hello" if (%a%)==() ( echo OK ) else ( echo ERROR )
bat 中的循环有些不一样。关键字也是for
。仍是先来看一个例子:
for /f "delims=: tokens=1,2,3" %%i in ( "2018:04:11" ) do ( echo %%i echo %%j )
这段脚本中须要注意的点是:delims=:
表示使用 ":" 来分割字符串,而tokens=1,2,3
则表示取出分割后的字符串的部分,从1开始。%%i
是循环中的每一个项。输出时%%i
和%%j
分别对应的就是截取的字段1和2。若是还须要输出第三个,也是使用%%k
表示,依次类推。
但 bat 中的for
会存在延迟赋值的状况,先来看一段脚本:
for /f "delims=: tokens=2" %%i in ( 'ipconfig /all ^| findstr /i "ipv4" ' ) do ( echo %%i set a=%%i echo %a% )
输出结果:
IPv4 地址 . . . . . . . . . . . . : 192.168.168.1(首选) IPv4 地址 . . . . . . . . . . . . : 192.168.2.160(首选 IPv4 地址 . . . . . . . . . . . . : 192.168.157.1(首选) IPv4 地址 . . . . . . . . . . . . : 192.168.2.160(首选 IPv4 地址 . . . . . . . . . . . . : 192.168.2.160(首选) IPv4 地址 . . . . . . . . . . . . : 192.168.2.160(首选
%a%
的值一直等于最后一项。
bat 中函数是使用:label
方式定义的,使用call
来调用:
call :test Hello World goto EXIT :test echo %1 %2 :EXIT
脚本中的goto
用来跳转退出,并且函数要放在脚本的尾部,存在多个函数时还须要使用goto
直接跳转,由于脚本是会按顺序执行下去的。
@echo off set option=%1 set address=%2 if (%option%) == () ( echo "Usage: connectIscsi.bat <start|stop> <address>" goto EXIT ) if (%address%) == () ( echo "Usage: connectIscsi.bat <start|stop> <address>" goto EXIT ) if %option% == start ( call :start %address% ) else if %option% == stop ( call :stop %address% ) else ( echo "Usage: connectIscsi.bat <start|stop> <address>" goto EXIT ) ::sc config msiscsi start=auto ::net start msiscsi goto EXIT :: 链接iscsi服务器 :start iscsicli QAddTargetPortal %1 for /f "delims= tokens=1" %%i in ( 'iscsicli ListTargets t ^| findstr /i "iqn.2018-11" ' ) do ( iscsicli qlogintarget %%i ) goto EXIT :: 断开iscsi服务器 :stop set a= for /f "delims=: tokens=2" %%i in ('iscsicli SessionList ^| findstr /i "fffffa8"') do ( set a=%%i goto return ) :return set a=%a: =0x% set a=%a:-=-0x% iscsicli LogoutTarget %a% iscsicli RemoveTargetPortal %1 3260 goto EXIT :EXIT
这个脚本是用来链接和断开iscsi服务器的。脚本有两个入参,option 和 address。链接和断开iscsi服务器。脚本的思路很简单,开始判断输入参数是否正确。而后根据 option 选择执行对应的函数。特别在:stop
中,由于延时复制的关系,因此循环体中只放简单的复制,处理部分在外面进行处理。
bat 的延时赋值有对应的解决方法:
SETLOCAL ENABLEDELAYEDEXPANSION set a=hello set a=!a! set a=!a:~1!