命令行脚本是包含可执行命令的文本文件,这些命令一般和命令行窗口键入的命令一致。脚本文件中的命令就是标准的文本字符,因此可以通过普通的文本编辑器,如 Windows 记事本来编辑。在脚本中输入命令时,需要注意的是,每一条命令,或者每一组需要一起执行的命令,都因该保存在脚本的单独一行中,以便确保命令的正确执行。

在常见的编程语言中,如 C/C++/C# 等语言中每条语句都要用分号来表示结束。而在命令行脚本中,没有诸如分号之类的特定终止符,而是通过断行(比如按下Shift+Enter键)、回车与断行(按下Enter键)、文件结尾标志三种方式来表示语句结束。

1、实用功能

1.1、为脚本添加注释

rem 命令用于注释单行命令,类似与 C# 等语言中注释符//。需要注意的是,当在批处理文件中通过 rem 命令注释了某一行之后,该行就不会被执行了,但默认被注释的命令内容还是会被回显到窗口上,这时候可以结合下面将要讲到的 @ 命令,写成 @rem 就一定不会显示了。

1.2、控制命令的回显

echo@两个命令,echo命令用于在命令回显消息、关闭或打开命令回显(当回显处于打开状态,执行批处理文件时将逐条显示批处理文件中的命令行;相反,当回显处于关闭状态时,不会显示命令行本身),而@命令用于以行为单位控制命令的回显方式。

示例 1:向命令行回显一条消息(Hello Word!)

echo Hello Word!

示例 2:关闭命令行回显(关闭回显之后就看不到命令提示符前的路径了)

echo off

示例 3:打开命令行回显(默认打开)

echo on

示例 4:在任何一行命令前加上@即可关闭该行的回显

@echo Hello Word!

1.3、使用数学表达式

命令行脚本支持算术运算、赋值运算、比较运算、按位运算等常见的数学运算。所有数学运算都得在set命令的参数/a之后进行。

示例:

set /a add=3+7
set /a sub=3-7
set /a mul=3*7
set /a div=5/2
set /a mod=5%2
set /a exp=2*2*2

1.4、向脚本传递参数

在调用命令行脚本的时候还可以向脚本传递参数。传递给脚本的每一个参数都可以用形参进行检查和解释。第1个参数用%1表示,第2个参数用%2表示,依次类推,第9个形参为%9。但如果向脚本传递的参数多于9个,则会被保存到一个特殊的参数变量%*中去,通过shift命令可以查看%*中的实参;另外在必要的时候,还可以通过shift命令进行形参移位,譬如shift /2表示忽略第2个参数,从第3个参数开始往前移动。还有一个特殊的形参是%0,它代表当前脚本的名称。

示例:

在 D 盘新建一个记事本,然后键入下面的脚本:

@echo 当前脚本的名称是:%0
@echo 第1个参数的值是:%1
@echo 第2个参数的值是:%2
@pause

将记事本改名为 try.bat,然后打开命令行(cmd.exe)调用该脚本:

try abc 123

结果如下:

2、使用变量

在命令行脚本中,我们通常所说的变量更可能是指环境变量。环境变量有多种来源,有内置在操作系统之中的,也有在系统启动时来自系统硬件的,这些被称之为内置系统变量,对所有 Windows 进程都可用。系统变量也可来自 Windows 注册表。除内置系统变量之外,还有一些登录时设置的变量,这种变量被称为内置用户变量。

通过set命令可以查看当前命令行实例中所有变量及变量值。除标准的系统变量和用户变量之外,还可以通过set命令在命令行中随时创建或设置变量。

有些变量在命令行中有着特殊的含义,如 path、computername、homedrive、errorlevel 等。其中 errorlevel 变量可以追踪最近使用命令的退出代码。如果命令正常执行,则错误级别为 0;如果命令在执行过程中出错,则错误级别会被设置为一个适当的非 0 值(1 表示一般的错误,2 表示执行错误,意味着命令没有正确执行,-2 表示算数错误)。

2.1、变量的命名及定义

在命令行脚本中,变量名是大小写不敏感的,在定义变量的时候可以区分大小写,但在调用的时候不区分大小写。变量名可以是任意字母、数字或字符的组合,如 2s、38、? 等理论上都是合法的变量名。尽管如此,我们也还是应该要使用便于理解的名字来做为变量名。

在命令行中声明变量时必须同时为其赋值,定义变量的语法如下:

set variable_name=variable_value

在变量名和变量值中,空格都是有效的,但一般不建议使用。命令行也不对具体的数据类型进行区分,所有的变量都是以字符的形式存储,即使变量值设置为数值也是如此。但在进行数学运算的时候,命令行是可以判断出字符串是否为数值的。

有些字符是命令行的保留字符,如 @、<、>、&、|、^ 等,在使用这些字符的时候,无论出现在变量值中的那个位置,都必须使用转码字符 ^ 对其进行转码。

示例:

set var1=abc
set var2=985
set var3=3.14
set var4="ok"
set var5="2^&3"
set "name=张三"

2.2、调用变量

在命令行中任何需要用到变量的地方都可以调用变量,调用的方式是用两个百分号包裹变量名,即%variable_name%

示例:

echo %var3%                       输出变量 var3 的值
echo %name% 输出变量 name 的值
cd %systemroot%\system32 切换到系统目录下的 system32 目录中
set syspath=%systemroot%\system32 定义一个变量 syspath 并用其它变量为其赋值

综合案例:

@rem 定义变量接收用户输入
@echo off
@set /p str=请输入任意内容,然后回车:
@echo 您刚刚输入的内容是:%str%
@pause

2.3、变量的作用域

在命令行中用set命令所做修改的作用范围是局部化的,也就是说set命令的作用仅限当前会话窗口,窗口关闭后之前的修改就会失效。

有时候可能还需要对变量的作用范围做进一步约束,使其仅作用于脚本的某一部分。要做到这一点,可以通过setlocal命令来标记一个局部范围的开始,使用endlocal命令来标记一个局部范围的结束。

示例:

setlocal
set cnt=5
endlocal

在一个比较长的作用范围内,使用完变量之后,应该要对其进行适当处理,以便释放该变量占用的内存,防止无意间再次引用该变量时出现预期之外的结果。在命令行中只要把变量的值设置为空,该变量就不复存在了。

示例:

set var3=

3、结构语句

3.1、选择语句

命令行中的选择语句是 if,该语句有 3 中不同的形式,本节将逐一介绍。

普通的 if 语句:如果条件为真则执行该语句,否则绕过该语句。

语法(语法中的圆括号并非必须,但使用圆括号会使语句结构更加清晰):

if condition (statement1) [else (statement2)]

示例:

set v1=1
if %v1%==1 (echo is one) else (echo is not one)
if %v1%==1 (hostname & ver & ipconfig /all)

如果存在 try.bat 文件,则把该文件的内容输出到控制台:

if exist try.bat type try.bat

if not 语句:如果条件为假则执行该语句,否则绕过该语句。

语法:

if not condition (statement1) [else (statement2)]

示例:

if not %errorlevel%==0 (echo error has occurred) else (echo running well)

if defined & if not defined:这两个语句用于检查某变量是否存在。

语法:

if defined variable_name statement
if not defined variable_name statement

在用于安全检查的时候,这两个语句非常有用。第一个语句是在变量存在的时候,执行某条命令。第二个语句是在变量不存在的时候,执行某条命令。

示例:

if defined v1 (echo %v1%)

3.2、迭代语句

命令行中的迭代语句是 for,该语句与常见的编程语言(如 C#)中的 for 循环有很大的不同。命令行中的 for 语句主要用于在成组的文件与目录中进行迭代处理,并以行为基础分析文本文件、字符串以及命令的输出信息。

最常见的 for 语句语法如下:

for iterator do (statement)

语法中的 iterator 用于控制 for 循环的执行。对 iterator 中每一个步骤或元素,都会执行特定的语句。它可以是单一的一条命令,也可以是使用命令管道、命令链、命令分组等技术组合起来的多条命令。

iterator 通常包含一个初始化变量和一组需要反复执行的元素,比如需要遍历的一组文件或某范围内的一组值。初始化变量也就是要使用的值的占位符,使用初始化变量时,需要注意以下几点:

  • 变量只存在于 for 语句的上下文中。
  • 变量名必须在 a~z 或 A~Z 的范围内,比如 %%a、%%b、%%c。
  • 变量名是大小写敏感的,也就是说,%%a 与 %%A 是不同的。

常见迭代形式表如下:

迭代功能 语法格式
文件集合 for %%variable in (fileSet) do statement
目录集合 for /D %%variable in (directorySet) do statement
子目录中的文件 for /R[path] %%variable in (fileSet) do statement
遍历一系列的值 for /L %%variable in (stepRange) do statement
分析文本文件、字符串以及命令输出 for /F[options] %%variable in (source) do statement

上表中提供的迭代形式也可以在命令行中交互式地使用 for 语句,这种情况下,应该使用 %variable,而不是 %%variable。除此之外,脚本中的 for 语句与在命令行中使用 for 语句是完全一样的。

遍历一系列值:用于操作数值。

语法:

for /l %%variable in (start,step,end) do (statement)

示例(输出 1~9 之间的奇数):

@for /l %%v in (1,2,9) do @echo %%v

在成组的文件中迭代执行:用于操作文件组中的文件。

语法:

for %%variable in (fileSet) do statement

语法中的 fileSet 用于指定需要处理的文件集,文件集可以是如下形式。

  • 通过文件名指定为单独的文件,如 myfile.txt。
  • 通过文件名通配符指定一组文件,如 *.txt。
  • 使用空格分割的多个文件或文件组,如 myfile.txt *.doc *.docx。

示例 1(输出 D:\Workspace 目录中所有 txt 文件的全路径名):

for %%i in (D:\Workspace\*.txt) do (echo %%i)

示例 2(输出 D:\Workspace 目录及其子目录中所有 txt 文件的全路径名):

for /r D:\Workspace %%i in (*.txt) do (echo %%i)

示例 3(输出 D:\Workspace 目录及其子目录中所有 jpg 或 png 文件的全路径名):

for /r D:\Workspace %%i in (*jpg,*png) do (echo %%i)

示例 4(输出 D:\Workspace 目录及其子目录中所有文件的全路径名):

for /r D:\Workspace %%i in (*) do (echo %%i)

示例 5(输出 D:\Workspace 目录及其子目录中所有名称包含 windows 的文件全路径名):

for /r D:\Workspace %%i in (*windows*) do (echo %%i)

示例 6(输出 D:\Workspace 目录及其子目录中所有路径包含 windows 的文件夹全路径+windows):

for /r D:\Workspace %%i in (windows) do (echo %%i)

从上述几个例子中也能看出来,匹配模式中第一个字符必须是星号,否则就匹配不到文件了。如果完全不带星号则会匹配到路径包含指定字符的文件夹全路径+指定字符。

在目录中迭代执行:用于操作目录组中的目录。

示例(输出 D:\Workspace\ 中所有的子目录名):

for /d %%v in (D:\Workspace\*) do echo %%v

3.3、子程序 & 过程

使用子程序:也就是通过goto跳转到另一段程序继续执行。goto的作用是将命令解释器直接跳转到批处理脚本中某个标记行。

示例:

@if not defined v (@echo error: Undefined parameters!) & (goto exit)
@if %v%==1 goto subroutine1
@if %v%==2 goto subroutine2
@if %v%==3 goto subroutine3
@goto exit :subroutine1
@echo In subroutine 1
@goto exit :subroutine2
@echo In subroutine 2
@goto exit :subroutine3
@echo In subroutine 3
@goto exit :exit
@echo Exiting...

使用过程:也就是在脚本中调用其它脚本,而又不会退出原脚本。进行过程调用时,命令行会执行调用的脚本,逐一执行其中的命令,结束后返回到原脚本,并从过程调用语句的下一行语句开始执行。

示例:

@if %v%==1 call file1

上例中,如果不适用call语句,也能调用 file1 脚本,但在 file1 脚本执行完毕之后控制权不会返回给调用者(原脚本)。

call 命令用于调用另外一个批处理文件。常用的方式就是call sample.bat,新扩展的一个用法是call :label arguments,也就是用 call 来调用 bat 文件内部的一段脚本,然后用 exit 来退出当前的 call 调用。

4、总结

本文主要讲述了命令行脚本的注释、回显、参数、变量、结构控制语句等基础内容。

本文链接http://www.cnblogs.com/hanzongze/p/cmd-script-base.html

版权声明:本文为博客园博主 韩宗泽 原创,作者保留署名权!欢迎通过转载、演绎或其它传播方式来使用本文,但必须在明显位置给出作者署名和本文链接!个人博客,能力有限,若有不当之处,敬请批评指正,谢谢!

探索Windows命令行系列(3):命令行脚本基础的更多相关文章

  1. 探索Windows命令行系列(5):几个实用的命令例解

    1.关机命令(shutdown) 2.管理 Windows 服务(sc) 3.管理任务进程(tasklist.taskkill) 4.显示 TCP/IP 配置值(ipconfig) 5.网络诊断工具( ...

  2. 探索Windows命令行系列(1):导航目录

    探索Windows命令行系列(1):导航目录 探索Windows命令行系列(2):命令行工具入门 探索Windows命令行系列(3):命令行脚本基础 探索Windows命令行系列(4):通过命令操作文 ...

  3. 探索Windows命令行系列(2):命令行工具入门

    1.理论基础 1.1.命令行的前世今生 1.2.命令执行规则 1.3.使用命令历史 2.使用入门 2.1.启动和关闭命令行 2.2.执行简单的命令 2.3.命令行执行程序使用技巧 3.总结 1.理论基 ...

  4. yii2 命令行执行php命令 commands(命令)

    YII2可以在命令行执行php命令,作为半路出家的撩妹君可谓是抠脚福音.作为一个屌丝级的程序员必须要有智能提示代码的IDE,比如PHPstorm.至于如何免费使用嘛..... 首先明白YII2自带的c ...

  5. liunx 命令行快捷键 常用命令

    常用指令 ls        显示文件或目录 -l           列出文件详细信息l(list) -a          列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir     ...

  6. 探索Windows命令行系列(7):通过命令编译C#类和Java类

    1.编译 C# 类 1.1.C# 编译工具 1.2.编译一个 C# 类 1.3.编译多个 C# 类 2.编译 Java 类 2.1.Java 编译工具 2.2.编译 Java 类 3.组合命令符 4. ...

  7. 探索Windows命令行系列(4):通过命令管理文件和文件夹

    1.文件夹操作 1.1.DIR(directory)命令 1.2.TREE 命令 1.3.CD(change directory)命令 1.4.MD(make directory)命令 1.5.RD( ...

  8. 探索Windows命令行系列(6):活用批处理解决实际问题

    1.批量修改文件名 2.批量重启服务 3.全盘搜索指定文件 3.1.全盘搜索名称为 mm.jpg 的文件,获取其全路径 3.2.查找系统中所有名称以 .docx 结尾的文件 4.调用可执行程序 4.1 ...

  9. 探索Windows命令行系列(4):通过命令操作文件和文件夹

    1.文件夹操作 1.1.DIR(directory)命令 1.2.TREE 命令 1.3.CD(change directory)命令 1.4.MD(make directory)命令 1.5.RD( ...

随机推荐

  1. Python实现脚本锁功能,同时只能执行一个脚本

    1. 文件锁 脚本启动前检查特定文件是否存在,不存在就启动并新建文件,脚本结束后删掉特定文件. 通过文件的判断来确定脚本是否正在执行. 方法实现也比较简单,这里以python脚本为例 #coding= ...

  2. dubbo 入门

    1 介绍 1.1 背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 1.2 说明 DUBB ...

  3. Welcome to my Blog

    Only English? Oh my god!!! why open live write can't write by Chinese?

  4. Zookeeper ZAB 协议分析

    前言 ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议.在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeep ...

  5. CentOS6.5下netcat工具安装教程

    1.下载下载地址:http://sourceforge.net/projects/netcat/files/netcat/0.7.1/下载的是netcat-0.7.1.tar.gz版本 2.拷贝用U盘 ...

  6. Python标准库--Scope

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 你一定在很多计算机科学课程上听说过作用域.它很重要, ...

  7. Python之日志处理(logging模块)

    本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模块日志流处理流程 使用logging四大组件记录日志 配置logging的几种方式 向日 ...

  8. Linux 库文件详解

    转自: http://www.cppblog.com/deane/articles/165216.html http://blog.sciencenet.cn/blog-1225851-904348. ...

  9. Flume简介及安装

    Hadoop业务的大致开发流程以及Flume在业务中的地位: 从Hadoop的业务开发流程图中可以看出,在大数据的业务处理过程中,对于数据的采集是十分重要的一步,也是不可避免的一步,从而引出我们本文的 ...

  10. Jedis-returnResource使用注意事项

    遇到过这样一个严重问题: 发布的项目不知从什么时候开始,每月会出现一两次串号问题.串号现象指的是,用户用账号A登录系统,然后某个时间,登录账号自动变成了B. 串号出现的时间不定,测试平台难以重现,且后 ...