飞翔灬吾爱的Blog
Windows | 批处理实现iscsi连接和断开
2020-3-19 fishyoung

最近搞了个私有云,然后搭建了iscsi,有个想法就是:笔记本用磁盘的时候,一键链接,或者一键断开。就考虑在windows系统上进行批处理操作,自动化的处理需要使用 windows 的的脚本。

基本的语法

首先从基础开始吧,之前都是使用 linux bash 的。可以说 windows bat 脚本和 linux bash 脚本还是有很多区别的。

设置变量

变量设置使用的命令为set

set a="hello world"

echo %a%

从上面的脚本中可以知道,使用set来设置变量,语法为set var=<>。如果要引用这个变量的话就使用%var%

注:bat 脚本不能像 bash 中一样设置临时变量,只用将变量设置为环境变量。

set命令的功能还是比较强大的,比如获取从键盘中输入的字符:

set /p a="Input a number:"

echo %a%

支持算术:

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
还有字符串的修改和截取:

:::::::::: 字符串的截取 ::::::::::

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 中仅仅是一个标记。

注: 使用 bat 中的注释时需要注意一点,不要再 () 的边上使用注释。

条件判断

bat 中的条件判断也是使用if

set a=1

if %a%==1 (

    echo OK

) else (

    echo ERROR

)

如果时判断字符串使用为空时,可以这样处理:

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直接跳转,因为脚本是会按顺序执行下去的。

实战操作[hide]

@echo off

set address="192.168.1.1"

title 设置iscsi处理方式

echo ★★★★请选择iscsi的处理方式★★★★

echo ▼连接iscsi————→请按 1

echo ▼断开iscsi————→请按 2

set /p option= 

if %option% == 1 (

    call :start %address%

) else if %option% == 2 (

    call :stop %address%

) else (

    echo "请输入数字1或者2"

    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.2020314" ' ) do (

echo "请稍等......"

        iscsicli qlogintarget %%i

    )

echo "连接成功,请再次检查......"

    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

echo "断开成功,请再次检查......"

    goto EXIT 

:EXIT 

@pause

[/hide]

这个脚本是用来连接和断开iscsi服务器的。功能就是:连接和断开iscsi服务器。脚本的思路很简单,开始判断输入参数是否是数字1 或者 2。然后根据数字选择执行对应的函数。特别在:stop中,因为延时复制的关系,所以循环体中只放简单的复制,处理部分在外面进行处理。

来张最后成功的截图:

 

后记

延时赋值问题

bat 的延时赋值有对应的解决方法:

SETLOCAL ENABLEDELAYEDEXPANSION

set a=hello

set a=!a!

set a=!a:~1!