windows bat腳本總結

最近項目須要再 windows 上作開發,並且一些自動化的處理須要使用 windows 的的腳本。因此作些記錄,防止遺忘。linux

基本的語法

首先從基礎開始吧,以前都是使用 linux bash 的。能夠說 windows bat 腳本和 linux bash 腳本仍是有不少區別的。windows

設置變量

變量設置使用的命令爲setbash

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!
相關文章
相關標籤/搜索