从批处理开始提高工作效率

Mar 26 2020

shell 脚本是 Linux/Unix(比如 Ubuntu系统 或者 Mac OS 系统中最常用的一种脚本语言),但我们不做开发,平时用 Windows 系统办公,跑不了 shell 该如何呢?(实际情况是,通过在 Windows 上安装 cygwin 环境也可以,但今天不做介绍)

那就从 Windows 原生的脚本 —— 批处理开始吧,它拥有非常简单的语法结构,不用编译就能执行的特点,我曾经用它编写了一个 Android adb 相关的指令集工具,并提供给同事使用,提高了大家办事的效率

本文通过对 uiautomatorviewer.bat,一个 Android 上用来启动控件结构查看工具的脚本的内容解析,带大家入门 “批处理”

它位于 %ANDROID_SDK_HOME%\tools\bin\uiautomatorviewer.bat

我这里以 google source 中的这个版本来解释:https://android.googlesource.com/platform/sdk/+/android-4.2.2_r1/uiautomatorviewer/etc/uiautomatorviewer.bat

第 1-2 行

1
2
1 @echo off
2 rem Copyright (C) 2012 The Android Open Source Project

Line 1: @ 符号表示执行时不会输出这一行的代码内容,如果不写的话,会在 cmd 命令行中把 “echo off” 字段显示出来。echo off 在这里的意思是后续的代码字段都不会显示到执行窗口中,也即不用每一行开头都写一个 @ 符号来隐藏代码

Line 2: rem 是注释关键字,表示这一行之后写的文本只是注释描述,不会当作代码执行

第 17 行

1
17 setlocal

setlocal 作用是本次批处理脚本中进行的参数设置只在当前脚本下生效,不会影响整个系统的设置

第 21 行

1
21 set prog=%~f0

set 关键字用来给变量赋值,这里对 prog 变量进行初始化,它的值为 %~f0,f 是 file 的缩写,这个值表示当前批处理脚本的绝对路径,所以是一个动态值,脚本放到哪里,它就表示哪个路径。这样的写法增强了脚本使用的灵活性

第 25 行

1
25 cd /d %~dp0

%~dp0 (dp 是 driver path 缩写),表示当前脚本所在目录的路径

这一行就是在命令行里切换到当前脚本所在目录下

第 29-30 行

1
2
29 call lib\find_java.bat
30 if not defined java_exe goto :EOF

Line 29: call 表示调用,由于 25 行切换到了脚本所在目录,即 %ANDROID_SDK_HOME%\tools\bin,则该行调用的是 %ANDROID_SDK_HOME%\tools\bin\lib\find_java.bat 这个批处理文件

Line 30: 执行 find_java.bat 的过程中,如果找得到 JDK HOME 目录,那么会给变量 java_exe 赋值。这一行用到一个 if 语句做判断,表达式为 not defined java_exe,如果表达式成立(即没有对 java_exe 赋值),则执行 goto :EOF,也就是不再执行后续代码,退出脚本

第 35-36 行

1
2
35 if exist %frameworkdir%%jarfile% goto JarFileOk
36 set frameworkdir=lib\

这是一个 if 语句,表达式为 exist %frameworkdir%%jarfile%,这里两个相邻 % 包裹起来的英文表示取这个变量的值, exist 表示判断这个文件是否存在,如果成立,则直接从标示有 JarFileOk (第 41 行 :JarFileOk)的地方开始往下执行,goto 用来控制代码跳转到任意位置用,如果表达式不成立,则进行 set 赋值操作

第 63 行

1
63 call %java_exe% -Djava.ext.dirs=%javaextdirs% -Dcom.android.uiautomator.bindir= -jar %jarpath% %*

这一行是综合脚本前述的参数,真正意义上启动实际程序的一行代码

在该行前面复制这一行的内容,并将 call 替换为 echo,就能看到这一行的真实执行面貌

1
D:\Tools\Java\JDK-8U~1\bin\java.exe -Djava.ext.dirs=..\lib\x86_64;..\lib -Dcom.android.uiautomator.bindir=D:\Tools\ANDROI~1\tools -jar ..\lib\uiautomatorviewer-26.0.0-dev.jar

echo 是用来输出文本的,可以输出字符或者变量的值

因此它把变量的值给输出,便于直观查看

实际上,启动uiautomatorviewer.bat 最终真正执行的是 uiautomatorviewer-26.0.0-dev.jar 这个 java 程序的代码

总结

今天通过介绍一个批处理文件 .bat 的实例,入门了几个常用的功能

@echo off 关闭代码行在命令行中的显示

set 变量赋值关键字

%~f0 脚本文件绝对路径

%~dp0 脚本文件目录路径

if 条件判断语句

goto 代码控制关键字

echo 文本输出关键字

%java_exe% 变量值的引用符号,双 %

call 调用其他的批处理或应用程序关键字