最近項目須要再 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!