我以前一直以为 bat 不能像 Linux 的 shell 一样设置函数并且调用, 事实上我发现这是可以的. 不过由于批处理的特性是一行一行执行的, 这种 label 的函数必须要写在文本的最后. 如果写在了批处理命令的前面, bat 会逐行运行里面的命令的. 写在文档的最后面, 并且在 "函数区域" 前跳过这些代码.
(顺便吐槽一下, 这种函数的写法和 Linux 的 shell 很不一样, shell 的 function 中的命令必须写在命令的前面, 让 shell 逐行运行一次, 才能在后面的命令中被人调用.)
函数的写法:
:: 在这个例子中我试图写的一个函数起名为 testfunction, 它的操作就是运行一个 echo 命令.
:: 使用 call 命令, 并且在后面写入函数名, 函数名的前方写一个: 代表这是一个 label.
call :testfunction
:: 这个 goto 命令让批处理在运行的时候跳过所有函数的部分.
goto EOF
:: 从下面一行开始就是函数的部分, 它们应该是 bat 脚本的最后部分, 理论上不应该在下方再写任何的命令了. 首先如同 goto 的命令一样, 首先要先写一个 lable
- :testfunction
- echo Test function is running.
rem exit /b 会让程序跳转到调用函数的命令处, 而不是直接退出程序.
exit /b
:EOF
:: 以上就是示例脚本的所有内容.
当然你可以不把函数内容写在这个 bat 中, 而是另外写一个 bat 文件, 然后 call 这个 bat 的绝对路径, 那也是可以的. 为了方便我就暂时称呼我运行的脚本名字为 a.bat, 而调用的脚本为 b.bat.
a.bat 的内容是.
- set a=aaa
- call b.bat
- echo %b%
- pause
而 b.bat 的内容是
- echo %a%
- set b=bbb
在这两个脚本中 a 脚本和 b 脚本各自定义了一个变量, 而没有定义另外一个脚本中定义的变量, 但是 echo 的又互相是对方脚本中定义的变量. 如果只有单独的脚本, 两个脚本的 echo 命令是返回不了任何内容的. 但是如果你运行了 a 脚本并且调用了 b 脚本, 可以发现, call 调用的脚本之间的变量是可以互通的. 不过脚本之间的 goto 的 label 不能互通, 即你不能在 a 脚本中 goto 到 b 的一个 label 中去.
而且不能不写 call 命令, 如果不写而是直接写 b 脚本的路径, bat 依旧可以运行, 不过运行完 b 脚本之后, 整个批处理就退出了. 例如我们将 a 脚本中的 call b.bat 中的 call 去掉, 那么脚本只会打印变量 a 的值, 然后赋值变量 b, 但是不回会到 a 脚本再次打印 b 的值.
通过 set /p 命令去获取另外一个文本文件里的值
写法是:
set /p var=<c:\path\to\file.txt
这样 file.txt 里的值就到了 var 这个变量里去了, 不过这个写法要求 txt 只有一行, 如果有多行, 那么也只会取第一行的内容.
那如果想要其他的行, 那么这个就要用到 for 循环了. 通过 for 循环可以读取文本文件 (或一个命令的结果) 每一行的特性, 将一行的内容赋值到一个变量里, 不过如果光写 for 循环而不使用计数器的话, 那么变量的值会被反复覆盖, 仅保留最后一行的值.
- set num=0
- for /f "tokens=1" %%i in ('wmic LogicalDisk where"Caption='C:'" get Size ^| find /v /i "size"') do (
- set /a num=!num!+1
- if !num!==1 (set C_size=%%i)
- )
要注意的是计数器由于是不停的变化的, 因此要用延时变量, 用! 包起来而不是 %, 而 for 循环的变量是 %% 连续两个百分号表示的. 如果输入的命令中有管道命令 |, 要用转移符 ^ 转译.
for 的 token 参数可以决定一行根据指定的分隔符 (默认是空格) 分割成几段, 取第几段. 如果你写的是表格的话, 那就是第几列, 而 num 计数器可以在 if 里找行. 这样的话这个循环就能取出列和行中的指定数据, 赋值到一个变量里.
在 bat 中调用 vbs.
当然本身的命令是非常简单的直接 call 就可以了, call xxx.vbs
不过这里要说的是将 bat 中的一些变量的值传递到 vbs 中去,
文件里调用
例如:
在 bat 中
- set a=testmessage
- call b.vbs /messageargs:%a%
在 vbs 中用
- set wshnamed=wscript.arguments.named
- msgbox wshnamed.item("messageargs")
这样的写法来获取 bat 变量.
以管理员身份运行 bat
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(Windows.close)&&exit
来源: http://www.bubuko.com/infodetail-3262477.html