自己是搞编程的,首先我是一个菜鸟,接触计算机这么久了,感觉很多计算机方面的技术和知识朦朦胧胧、模模糊糊,貌似有些贻笑大方了;所以最近腾出了点时间来了解计算机的基础知识,准备整理整理这些知识,我想也为时不晚。
首先,我是一个后生,自从接触计算机开始就一直使用的Windows操作系统,而且还是较为古老的XP系统(相对Win7、Win8而言),可能是用的得心应手的,到现在还没准备换。
为什么要从批处理开始讲起?首先内心是有一点的崇拜“黑客”,那NB的技术真让人羡慕,当然我不会立志去成为一名“黑客”,因为这个职业是会被和谐的。那到底是为什么呢?因为当Windows还在娘胎的时候,DOS(全称为Disk Operating System,被称为磁盘操作系统)是计算机操作系统的霸主,而批处理就是汇集DOS的寄住。
计算机本身是弱智的,只能识别0和1两个数字(0和1这两个数字被我们尊称为二进制数码),但是人类的智慧是无限的,通过对计算机大脑(CPU)的改造,可以让它支持整个宇宙的所有信息。回归正题,我们在计算机上查看的任何文件都是以0和1组成的二进制码存储在计算机中的,具体怎么存储的我也是后生,所以我也不懂。最早出现的磁盘操作系统(DOS)就是实现对计算机硬盘上的文件的操作和管理。说了这么多其实只想说明一点就是我很想知道DOS和批处理到底是怎么对计算机硬盘上的文件进行操作的?
上面说了很多废话,下面直接入题。
DOS(Disk Operating System),磁盘操作系统,我想对计算机有点了解的人应该都不会陌生这个词,但是具体它是干什么的呢?DOS是计算机上的一种基于磁盘管理的操作系统,可以直接操作和管理磁盘上的文件,在计算机出厂是基本都会自带一个DOS磁盘操作系统。
DOS发展到现在已经存在很多版本,以MS-DOS、PC-DOS和FreeDOS最为常见。
MS-DOS(Microsoft-Disk Operating System),是微软的磁盘操作系统,是DOS的一个分支。MS-DOS的来历可以查阅一下资料,最早的DOS称为86-DOS,最后由微软创始人比尔?盖茨以5美元(来自《硅谷传奇》电影,有时间可以看一看,讲述了乔帮主和盖茨大叔的白手起家之路)收购版权并更名为MS-DOS。
初期的Windows操作系统实质是基于DOS系统的一种图形应用程序,直到Windows2000后,才脱离DOS本质开始了自己的视窗操作系统。虽然脱离了DOS,直到Win7,Windows操作系统中一直保留了MS-DOS系统应用,可能是它曾经是霸主的原因。现在MS-DOS的最新版本是6.x,微软已经宣布停止对MS-DOS系统的更新,当然我们了解一下还是非常有必要的。像我这种不求新的人还在用着XP系统,情何以堪啊!所以我下面讲到的都是基于Windows XP系统的,当然大部分Windows 7一样可用。
Windows中的磁盘操作系统称为MS-DOS,DOS在Windows中表现为一个黑底白字的窗口,我们亲切的称之为命令行。对Windows熟悉的人肯定都知道在“开始”菜单中有一个“运行”窗口,我们可以在其中输出程序的名称,然后就可以直接打开对应的程序了。所以我们可以在“运行”窗口中的“打开”文本框中输入“cmd”即可以打开期待已久的命令行窗口。“cmd”其实是“command”(命令)的单词缩写。
环境变量的知识,我就提到这里,其实有很多内置的系统环境变量,这些变量的作用,你可以不用吝啬网络资源,自己去查找一番(“百度”不行去“谷歌”),相信比我讲的透彻。
当在“运行”窗口中输入“cmd”之后键入“回车键”,即可启动命令行窗口,可以看到它很是淳朴,单纯的黑底白字,如图:
虽然它很朴素,但是功能是不可小觑的。我们可以看到一个一个一闪一闪的白色下划线,其实它就是我们称之为的“光标”。
下面我们在命令行窗口中输入“help”,然后键入回车,可以看出得到了一个命令说明列表,列出了所有的MS-DOS命令行以及命令行工具命令,列表如下:
从列表中可以看成,有些命令是有对应的应用程序的,而且这些应用程序都是存在于“WINDOWS\system32”目录中,所以这些命令我们称之为“外部命令”;而对应那些没有对应应用程序的命令都是MS-DOS内部保留的命令,称为“内容命令”。
了解编程的人都知道,单纯的一个命令符只能做一件唯一的事情,所有MS-DOS对每一个命令都进行了扩展,这种扩展称为“命令选项”,大部分的命令选项都是可选的,使用“命令+选项”的方式可以实现多种复杂的不同的操作(值得注意的是命令选项和命令之间通常使用空格分割)。这里介绍一个绝大多少命令都保留的一个默认命令选项“/?”,这个选项用于查看命令的使用说明文档信息。例如:我们在命令行中输入“cmd /?”就可以看到“CMD”命令的使用说明信息以及其所有选项描述信息。
从上面的几个简单的例子,其实可以看成MS-DOS命令的几个特点,下面来总结一下:
MS-DOS是磁盘操作系统,目的用于管理和操作磁盘上的文件。因此它是基于目录的文件管理程序,也就是在操作之前必须要指定操作的目录。
命令行中命令、命令选项以及命令参数是不区分大小写的。这是Windows系统的共性,Windows中的目录和文件名都是不区分大小写的。也就是说MS-DOS中的大多数情况下是不区分大小写的,在某些特定情况下是需要区分的,这个以后你自会慢慢体会的。
命令行的结束符号是换行符(包括Enter键等),有的时候空白符(包括Tab键、Space键等)也可以作为结束符。也即是说一个换行符表示一条命令语句。
命令和选项以及参数之间的分隔符是空白符(包括Tab键、Space键等),某些特定情况下空白符可以省略。
MS-DOS是单任务系统,只有执行完一项操作后才能执行下一项操作。当我们执行完某一项操作后会回到系统起始状态。
命令行的执行快捷键是“Enter键”,强制终止的快捷键是“CTRL+C”键。
上面已经提到可以使用“命令 /?”的方式来查看任意一种命令的使用说明信息以及所有选项描述信息,通过这种方式我们可以学习以上列表中的任意一种命令的使用方式。只要肯尝试就没有不懂的。下面只介绍几种常用的命令使用方式。
盘符,官方应该称为卷标,就是我们说的“C盘”、“D盘”中的字母“C”和“D”,一般情况下盘符都是以26个英文字母大写方式加上冒号的方式呈现的,例如C:表示C盘,D:表示D盘,用于标记某一个磁盘分区。通常情况下我们的Windows系统都是安装在C盘的,因此启动命令行默认的操作目录是“C:\Documents and Settings\当前用户”。那么问题就来了,我们如何切换到其他的磁盘分区下进行操作呢?MS-DOS中提供了一种非常简单的操作方式,就是直接输入盘符,即:
卷标名称:
可以直接输入“盘符:”即可切换到该盘的根目录中,当卷标无法找到则会提示错误并返回到上一次操作的目录位置。
注意:这种方式不能从当前盘符中的目录切换到当前盘的根目录,只能切换到其他盘的根目录。
CD/CHDIR——目录切换和显示
“CD”或“CHDIR”是短语“change directory”的缩写,意思是改变目录。主要用于改变当前目录或显示当前目录完全路径名。用法如下:
CD|CHDIR [/D] [目标目录]
“[]”表示可选,相信只要学过编程应该都知道。实质该命令有两种用法,一种是显示当前工作所基于的目录完全路径名;还一种就是改变工作目录到另一个地方。
讲到路径,这里可以大胆的扩展一下,所谓“路径”通过计算机中资源的一种定位标识途径,主要目的就是用于资源的唯一性定位。在通常情况下“路径”分为“绝对路径”和“相对路径”两种形式:
绝对路径——从命名上可知它的位置是固定的,它是通过一种磁盘文件标识符来进行定位的,描述的是“某个磁盘下的某个位置”的意思,通常包含盘符。
相对路径——从命名上可知它的位置是相对的,必须存在参照物,然后才能表示相对这个参照物而言资源的位置,描述的是“相对当前位置的某个位置”的意思,通常不包含盘符,但是包含“..”、“.”、“\”等操作符,“..”表示上一级目录,“.”表示当前目录,“\”表示当前盘符的根目录。
Windows系统中使用“\”作为目录级别分割符号(当然也可以使用“/”,但是Windows不推荐使用“/”);使用“..”可以表示上一级目录,使用“.”可以表示当前目录,使用“\”表示当前盘符的根目录。在MS-DOS中大多数使用的都是绝对路径,但是使用相对路径更加灵活多变。接下来我们再来讲“CD”命令的用法。
上面我们遇到了一个问题,就是如何从当前盘符的某一个目录切换到当前盘符的根目录,直接使用盘符切换显然是不行的。所以这里我们可以使用“CD \”的方式切换到当前盘符的根目录;同时我们可以使用“CD ..”切换目录到当前目录的上一级目录。其实就是目标路径是多变的,目标路径可以是相对路径,同样可以是绝对路径;默认情况下当目标路径为绝对路径的时候不能跨磁盘分区进行切换,所以“CD”命令提供了“/D”选项用来解决这个问题,例如我们在默认的MS-DOS路径下输入“CD /D D:\test”可以直接进入D:\test目录,当缺少“/D”选项时就不可以了,所以“CD /D”方式也可以替代盘符切换方式进行盘符的切换。
MD/MKDIR——目录创建
“MD”或“MKDIR”是短语“make directory”的缩写,意思是构建目录,主要用于创建新的指定目标目录路径名称的目录。用法如下:
MD|MKDIR 目标目录路径
该命令用于创建目录,其必须指定要创建目录的完全路径名。该命令可以跨磁盘分区进行目录创建,同时还可以创建一个目录树结构,即同时创建多个不存在的嵌套目录结构或目录组。
目标目录路径可以使用绝对路径,也可以使用相对路径,需要注意的时,目录不能与存在的目录名相同,否则会提示错误。注意:当创建的目录名称中存在空白符时需要使用英文状态下的引号("")将目录名称引起来;否则将创建目录组,每一个目录名以空白符分割开。
RD/RMDIR——删除目录
“RD”或“RMDIR”是短语“remove directory”的缩写,意思是移除目录。主要用于删除指定的目录结构。用法如下:
RD|RMDIR [/Q] [/S] 目标目录路径
该命令主要用于空的目录,可以跨磁盘分区进行操作,同时还可以使用增强选项删除非空的目录结构。只需要指定目标目录路径即可,该路径可以是绝对路径也可以是相对路径。
默认情况下,“RD”命令只能删除空的目录,也就是目录中不能存在其他目录或文件,否则会提示错误,正出于这个原因,所以“RD”命令提供了“/S”选项,用于强制删除非空目录,当使用“/S”进行非空目录的强制删除时会提是确认删除信息,当然可以使用“/Q”选项强制取消提示信息。
使用“RD”进行目录的删除一般不推荐使用,因为就我目前所知,使用DOS删除的文件或目录不会保留在“回收站”中,所以不要轻易的删除重要文件,否则删除后就不会那么轻易的找回来了。
DIR——目录内容展示
“DIR”是短语“directory”的缩写,表示目录。主要用于目录内容查看和展示。用法如下:
DIR [目标目录路径] [选项]
该命令主要用于目录结构信息的查看,可以查看目录中的子目录和文件属性信息。不指定“目标目录路径”的“DIR”命令用于展示当前目录结构,当指定“目标目录”时则展示目标目录的目录结构,格式为日期、时间、类型、大小、名称。该目录支持跨磁盘分区操作。
“DIR”提供的磁盘选项比较丰富,可以通过“dir /?”或“help dir”来查看所有的选项以及其说明信息。这里提一下,“/L”选项可以将子目录或文件名称转换为小写格式;“/S”选项可以展示每一个子目录的目录结构;“/X”可以将展示的结果强制转换为短名称的模式。
TREE——目录树展示
“TREE”命令和“DIR”命令用法差不多,同样用于展示指定目录的内容结构,它的特点是使用一个“树形”结构展示目录所有子目录和文件以及子目录中的所有子目录和文件;而“DIR”则是以列表的方式展示目录结构。用法如下:
TREE [目标目录路径] [/F] [/A]
该命令主要是以“树形”结构的方式展示目录结构。不指定“目标目录路径”的“TREE”命令用于展示当前目录结构,当指定“目录目录”时则展示目标目录的目录结构。该命令不支持跨磁盘分区操作。
该命令包括两个选项,其中“/F”选项用于展示出所有的文件信息,默认只是展示目录结构,不包括文件列表;“/A”用于标识强制使用ASCII字符进行结构图案的构建。
TYPE——文件内容查看
“TYPE”命令并不是表示文件类型,而是用于查看文件内容的命令。这里需要注意的是“TYPE”命令可以查看所有文件的内容并将其打印在命令行窗口,但是大多数的文件都是经过编译以及其他方式处理过的,所以这些文件的内容则算一系列乱码,因此是无意义的查看,所以我们通常使用“TYPE”命令查看文本文件的内容,使用方式如下:
TYPE 目标文件路径 [|MORE]
该命令主要用于文本内容的信息查看,所以“目标文件路径”必须指定,路径既可以是相对路径,也可以是绝对路径,同时该命令支持跨磁盘分区操作。
使用“TYPE”命令只能查看一个特定的文件内容,如果文件内容过多,则可以使用“|more”选项来实现分页显示的效果。其实“MORE”是一个命令,“|”是一个特殊的符号。
COPY——文件复制/文件合并
“COPY”命令主要用于文件的复制,可以将一个或多个文件复制到另一个位置,使用方式如下:
COPY [选项] 源文件路径 [/A或/B] [+...] [目标文件路径 [/A或/B]]
该命令主要用于实现文件副本的创建,支持跨磁盘分区操作。
这里我们来看看“/A”和“/B”的区别,它们是紧跟在文件后的选项,其中“/A”用于表明文件为ASCII文本文件;而“/B”用于表明文件为二进制文本文件;但大多数我们不实用则两个选项进行表明。
“COPY”命令的选项比较丰富,可以通过“copy/?”或“help copy”来查看所有的选项以及其说明信息。默认情况下,可以直接指定“目标路径”为一个目录,而且这个目录必须存在,否则会提示错误(可以使用“/D”强制创建目标目录),则命令会将源文件复制到目标目录中,这个过程叫做“同名拷贝”;当然也可以指定“目标路径”为一个文件,这种方式是将源文件内容读取并写入到目标文件中,这个过程叫做“异名拷贝”。
XCOPY——文件或目录树复制
“XCOPY”命令主要用于目录树的复制操作,同时支持对文件的复制操作,可以将一个或多个文件或目录复制到另一个指定的位置。用法如下:
XCOPY 源路径 [目标路径] [选项]
该命令主要用于目录树结构的复制操作,其次可以扩展为文件的复制操作,其中“源路径”必须要指定,如果没有指定“目标路径”则默认目标路径为当前工作目录。支持跨磁盘操作。
“XCOPY”命令的选项比较丰富,可以通过“xcopy/?”或“help xcopy”来查看所有的选项以及其说明信息。默认情况下,如果不实用任何选项,则在完成复制之前会提示选择“目标路径的类型,F表示文件,D表示目录”;如果选择目录,则会将源路径目录和目录下的非系统、非隐藏文件复制到指定的目录路径下;如果选择的是文件,则会将目录下的每一个文件内容依次复制到目标路径中,后者会覆盖前者,而且在复制每一个文件时都会提示是否重写目标路径文件。当然可以使用“/I”选项将目标路径强制作为目录进行处理从而取消目标路径类型的确定提示。
默认情况下“XCOPY”命令只能复制一层目录和其文件,同时提供“/S”选项则可以将非空的目录和其下的非系统、非隐藏文件(包括子目录层)复制到指定的目标路径中;使用“/E”选项可以将所有的目录和非系统、非隐藏文件复制到目标路径中;使用“/T”选项则可以值对非空的目录和子目录结构进行复制(不包含文件的复制);使用“/H”选项则可以强制将系统文件和隐藏文件复制到目标路径中;当然它们也可以进行组合使用,达到不同的效果。
“/F”选项可以输出完整的元老级和目标路径中的复制映射关系;使用“/L”选项可以输出源路径中需要复制的文件列表等。
DEL/ERASE——删除文件
“DEL”是短语“delete”的缩写,意思是删除;还一种删除文件的命令是“ERASE”,意思是擦除,二者使用方式一样。在这里主要指删除文件,该命令可以删除一个或多个文件,是直接从磁盘上擦除文件的数据,所以删除的文件并不会出现在“回收站”中,因此要谨慎使用。用法如下:
MOVE [/Y或/-Y] 源路径 目标路径
该命令用于从磁盘上擦除一个或多个文件数据,其中“目标路径”必须指定,可以是绝对路径,也可以是相对路径。支持跨磁盘操作。
“DEL”命令的选项比较丰富,可以通过“del/?”或“help del”来查看所有的选项以及选项说明信息。其中“/P”选项可以开启删除文件前的确认提示信息,默认是不开启的;“/F”选项可以强制删除只读文件,也就是说默认情况下,不支持只读文件的删除;“/S”选项可以将“目标路径”指定为一个目录,那么将依次删除该目录中的文件并同时删除该目录的子目录以及子目录的子目录中的文件。
MOVE——移动文件或目录/重命名文件或目录
“MOVE”意思是移动,该命令主要用于移动目录,相当于Windows中的“剪切”操作,可以将一个或多个文件移动到指定的路径中;同时可以衍生对目录或文件的重命名操作,即将一个目录或文件移动的不同名的目标路径中。用法如下:
DEL|ERASE [选项] 目标路径
该命令有两个用法,其一就是移动文件,其二就是重命名目录或文件。其中源路径和目标路径必须指定,该命令有两个选项,“/Y”选项用于取消移动时的确认提示信息,“/-Y”选项用于显示确认提示信息。
当移动文件操作时,即源路径是一个文件,目标路径可以为一个目录路径,那么会将源路径中的文件移动到目标路径的目录中(文件名保留);如果目标路径为一个文件路径,那么会将源路径中的文件内容读取并写入到目标文件中,这样可以实现文件的重命名操作;当源文件存在多个时(使用英文状态的“,”分割),则命令会将多个文件移动到同一个目标路径中,或者将多个文件的内容读取并拼接后写入到一个目标文件中。
当源路径是一个目录时,可以将源目录移动到指定的目标路径中,如果目标路径与源路径在同一个相对路径中,则可以进行目录的重命名操作。注意:“MOVE”命令可以实现文件或目录的移动(或重命名),但是只能支持文件的跨磁盘分区移动,不支持目录的跨磁盘分区移动。
REN/RENAME——重命名文件或目录
“REN”或“RENAME”意思是重命名,可以对一个指定的文件或目录进行名称的修改。用法如下:
REN|RENAME 源路径 新名称
该命令用于修改文件或目录的名称,其中源路径和新名称必须同时指定,需要注意的是“新名称”不能包含新的路径,它的路径沿用“源路径”中的路径地址;该命令支持跨磁盘分区操作。
FC——文件比较
“FC”是短语“file compare”的缩写,意思是文件比较。该命令用于进行两个文件的内容信息比较,毕竟是命令行,所以“FC”进行的文本文件内容的比较是比较弱智的,不推荐使用,当然如果在没有其他文件比较工具的时候可以勉强使用一下。用法如下:
FC [选项] 文件路径1 文件路径2
该命令用于文件内容的比较,然后显示出内容的不同之处,支持跨磁盘分区文件的比较。同时提供多个选项,可以使用“fc/?”或“help fc”来查看选项的使用说明。
FIND——文件内容搜索
“FIND”,意思是查找,该命令主要用于在指定文件的内容中搜索指定的字符串,并显示相应的结果。相当于对内容的查找操作。用法如下:
FIND [选项] "字符串" [文件路径]
该命令用于字符串的搜索操作,其中要搜索的字符串必须使用英文状态的“""”引起来,而且该字符串是必须参数;文件路径不是必须的,但是大多时都是从存在的文件中进行内容字符串的查找,如果文件路径不存在则将在接下来输入的内容中进行查找(按CTRL+C组合键可以终止查找)。该命令支持跨磁盘分区操作。
默认情况下,在内容中查找到指定的字符串后会打印输出存在该字符串的一整行内容。当然还提供了丰富的选项控制,可以使用“find/?”或“help find”来查看所有的选项说明,其中“/V”选项可以显示输出不包含查找字符串的行内容;“/C”选项可以输出包含查找字符串的行数;“/N”选项可以显示包含字符串的行号和行内容;“/L”选项可以指定搜索过程中严格区分字符串的大小写,默认是忽略大小写的。当然这些选项都可以组合使用,可以达到不同的效果。
FINDSTR——文件内容搜索
“FINDSTR”意思是查找字符串,该命令与“FIND”命令的作用大致相同,都是用于字符串的查找工作;当然“FINDSTR”命令比“FIND”命令功能更为复杂多变,同时它支持对一个目录中所有文件的搜索功能。用法如下:
FINDSTR [选项] 字符串 [文件路径]
该命令同“FIND”命令一样,用于在文件内容中进行字符串的搜索查找,然后打印输出对应的结果。其中要查找的字符串可以使用英文状态的“""”引起来,也可以不实用,但是字符串必须指定;文件路径同“FIND”命令一样可以不指定,当不指定时表示在接下来输入的内容中进行查找。该命令支持跨磁盘分区操作。
使用“FINDSTR”命令可以实现多个字符串的查找,多个字符串需要使用空格符号隔开,同时必须将字符串使用“""”引起来,否则则解释为命令选项。同时“FINDSTR”还支持表达式的扩展查找,支持字符串范围的查找等等,可以使用“findstr/?”或“help findstr”来查看具体的使用说明。
与“FIND”命令一样,默认情况下,在内容中查找到指定的字符串后会打印输出存在该字符串的一整行内容。当然还提供了丰富的选项控制,可以使用“findstr/?”或“help findstr”来查看所有的选项说明,其中“/I”选项可以指定搜索过程忽略大小写,默认是严格区分大小写的;“/X”选项可以筛选出完全匹配的行内容并显示输出。用法比较灵活,可以尝试选项组合使用,从而达到不同的效果。
PATH——执行路径管理
“PATH”命令是比较关键的一个命令,但是在使用时用的并不是很多。该命令主要用于设置MS-DOS系统环境变量中的“PATH”常量值,也就是MS-DOS执行环境变量中的“PATH”变量。用法如下:
PATH [目标目录路径][;...][;%PATH%]
“PATH”在MS-DOS系统中指可执行路径,使用该路径指定后,以下在引用某一个(非路径的)资源的时候就可以优选从“PATH”变量指定的可执行目录中进行资源的搜索和查找,这一点比较灵活。
没有指定“目标目录”的“PATH”命令用于查看当前系统注册表中的“Path”环境变量;当指定“目标目录”时则将“PATH”当前MS-DOS环境中的“PATH”环境变量修改为指定的目录,当然可以包含多个目录,使用“;”分割;如果要在原有的“PATH”环境变量中追加目录可以使用“%PATH%”进行原有环境变量的引用(这种用法其实是一种变量的引用方式)。
DATE——日期管理
“DATE”意思是日期,该命令用于管理系统日期信息。输入没有参数的“DATE”命令可以显示当前日期,并提示修改新的日期。使用“/T”选项可以取消修改步骤,只输出当前日期;使用带日期值作为参数的“DATE”命令用于修改当前日期为指定的日期。
“TIME”意思是时间,该命令与“DATE”一样,主要用于管理系统时间的信息。输入没有参数的“TIME”命令可以显示当前时间并提示修改新的时间。使用“/T”选项可以取消修改步骤,值输出当前时间;使用带时间值作为参数的“TIME”命令可以修改当前时间为指定的时间。
CLS——清屏
“CLS”命令用于清除当前屏幕内容。当屏幕内容较多是可以使用“CLS”命令清除当前屏幕中的所有内容,并将工作路径返回到执行命令前的工作路径。
EXIT——退出
“EXIT”意思是退出,该命令用于退出当前命令行程序,需要注意的是只能结束当前一个命令行程序,而不是所有。结束后将关闭命令行窗口。高级应用可以使用“exit/?”和“help eixt”来查看。
HELP——帮助查看
“HELP”意思是帮助,上面都提到过,主要用于输出命令行帮助信息,它有两种用法:其一就是打印所有的MS-DOS命令行命令说明信息列表,其二就是查看单个命令的使用说明文档。使用方式为:
HELP [命令]
该命令用于帮助说明文档的查看,大多数情况下MS-DOS命令提供“/?”选项来实现同样的效果。
format——磁盘格式化
“format”命令也提供了丰富的选项操作,可以使用“format/?”或“help format”查看,可以将一个磁盘分区格式化同时修改其文件系统格式、修改其卷标名称等。较为常用的一种方式就是快速格式化“format 盘符 /Q”,这种方式可以快速的实现格式化操作,同时保留原有文件系统格式。
convert——磁盘格式转换
“convert”命令也提供了丰富的选项操作,可以使用“convert/?”或“help convert”查看,这种转换是不会擦除磁盘原有数据的,只是重构它的文件系统而已。最常用的方式为“convert 盘符 /FS:NTFS”,即将指定的盘转换为NTFS格式,注意当前工作分区不能进行转换。
chkntfs——启动时磁盘检查设置(自检设置)
“chkntfs”是Windows提供的一个磁盘检查设置工具,所谓的“磁盘检查”就是我们称之为的“自检”,还在为由于非正常关机而导致系统在下一次启动是出现蓝屏自检而烦恼吗?哈哈...使用“chkntfs”工具可以帮你取消磁盘的自检过程。使用该命令必须要指定要操作的磁盘分区卷(即盘符),经过实际验证该工具只能对“NTFS”格式的磁盘进行有效的设置。
“chkntfs”命令也提供了丰富的选项操作,可以使用“chkntfs/?”或“help chkntfs”查看,可能这个命令对我们有用的就是用于取消磁盘的自检过程。取消的命令如下:
ping——TCP/IP远程连接测试
“PING”命令,做过编程的应该都知道这个命令,至于TCP/IP实在是高深莫测,这里不做多的介绍,可以去查一下相关资料,初学者知道它是支持上网的东西就行了。“ping”命令主要是用于测试对远程主机的网络连接状况,通过这个状况我们可以知道与目标主机的网络是否通畅。用法如下:
PING [选项] 目标主机地址
该命令用于测试与目标主机的网络连接,所以目标主机的地址一定以指定,通常我们使用IP来表示网络中的一台计算机,所以目标主机地址可以是主机IP地址,还可以是目标主机的域名地址。
“PING”命令提供了丰富的命令选项,可以通过“ping /?”来查看其所有的选项和说明信息。
ipconfig——TCP/IP信息查看
“IPCONFIG”命令,是程序员应该都知道的命令,该命令主要用于查看本机的IP配置信息,通常我们使用这个命令来查看本机的IP地址。用法很简单:
IPCONFIG [选项]
该命令用于查看本机当前网络连接配置的IP地址、网关等信息。
通常情况下,我们可以通过网络连接的属性来查看本机IP地址,但是对应那些自动获取网络地址的机器你就束手无策了吧!呵呵...我们可以使用“ipconfig”命令来查看。“ipconfig”命令提供多种选项操作,可以使用“ipconfig/?”来查看这些选项的使用说明信息,默认情况下无选项的“ipconfig”命令可以查看当前打开的网络连接的IP地址、子网掩码以及网关信息;可以使用“/all”选项可以查看完整的本机网络信息,包括主机名、本机物理地址(MAC)、IP地址、子网掩码、网关、DNS服务器等信息。
net——网络环境、服务、用户等综合管理
“NET”是Windows综合型管理工具,可用于管理网络环境、服务、用户、登录等Windows中大部分重要的功能模块,同时支持远程计算机的管理。“net”命令是一个组合型命令,可以使用“net”或“net/?”来查看该命令的所有组合项。
对应我来说最常用的就是它对服务的管理,可以使用“net”命令与“start”命令组合来实现服务的启动操作,与“stop”命令的组合实现服务的停止操作。使用方式如下:
注意:服务名称可以通过服务选项模块中的查看。
netstat——网络连接信息查看
“NETSTAT”是TCP/IP模块提供的网络状态查看工具,可用于查看网络统计和当前网络连接信息。其实在做编程开发的过程中,“netstat”命令还是有必要了解的,尤其是Web开发中,我们可以使用“netstat”命令查看端口占用情况。用法很简单:
NETSTAT [选项]
通常情况下,没有选项的“netstat”命令,用于查看本机的TCP连接情况,结果是一个本机与连接主机的映射地址以及状态信息的列表。其实对我来说有用的基本就是用它来查看“端口号的占用情况”了。该命令提供了丰富的选项,可以通过“netstat/?”来查看,其中“/a”或“-a”选项用于查看当前主机所有的连接和端口监听情况,不仅包含TCP还包含UDP;“/b”或“-b”选项可以查看每个连接或监听端口对应的可执行组件完全路径名;“/n”或“-n”选项可以将显示中的信息强制扩展为数字模式,即IP和数字端口表述信息。
telnet——远程连接
“TELNET”实质是TCP/IP模块提供的一个网络客户端工具,可以使用该工具登录网络上的远程主机。话说这个命令行工具是比较强大的,可以实现数据包的发送的接受,哈哈...真是因为其强大,所以我还不怎么会使用,当然你可以好好研究研究。我曾经看到过一个例子,就是使用“telnet”命令来实现模拟HTTP访问远程主机,如果是一个站点则会打印出站点首页的HTML代码。使用“telnet”登录远程主机一般使用以下的方式:
其中“hostname”是指主机的唯一标识名称,可以是IP、域名等;“port”表示的是端口号,默认为“23”。
msg——消息发送
“MSG”实质是TCP/IP模块提供的网络消息发送客户端工具,可以在使用“msg”命令实现网络上的消息传输功能,当然不能实现过于复杂的消息传输。用法比较简单:
MSG 目标用户 [选项] 消息
在模拟过程中“目标用户”一般都是指本机用户名,当然还可以是远程主机的用户名。例如使用“msg * 123”可以给本机所有的用户发送消息“123”,本机用户可以在弹出会话框中阅读消息。
tasklist——系统进程查看
“TASKLIST”是Windows提供的一个关于进程的监听工具,该工具可以显示本地或远程主机系统上运行的任务或进程信息列表。其实和Windows系统中的任务管理器中的进程选项列表一致,只不过“tasklist”命令默认不会刷新而已。默认情况下,无选项参数的“tasklist”命令用于显示系统当前时刻所有进程的名称、ID、内存使用等信息;当然还提供多种选项操作,可以使用“tasklist/?”来查看。
taskkill——系统进程终止
“TASKKILL”是Windwos提供的一个进程管理工具,该工具与“tasklist”工具非常相识,但是功能不一样。“taskkill”命令可以结束本机或远程主机上至少一个指定ID或名称的进程。具体使用方式可以使用“taskkill/?”来查看。
需要提出的是,Windwos系统还提供了一个进程管理工具叫“TSKILL”,与“taskill”的用法差不过,使用时需要指定一个进程ID或者进程名称,由于“tasklist”可以查看进程ID和名称,所以一般需要与“tasklist”命令相结合使用。
edit——文本编辑器(最基本的DOS级别的文本编辑器)
nslookup——域名和DNS侦测工具(可以检查指定域名对应的IP地址)
shutdown——计算机关机、注销、重启命令行工具
regsvr32——系统DLL组件管理工具
calc——计算器程序
clipbrd——系统剪切板管理工具
dxdiag——DirectX信息检查工具
notepad——记事本程序
regedit——注册表编辑器
control——控制面板
taskmgr——任务管理器
write——写字板程序
winmsd——系统信息查看面板(Windows提供的系统、硬件、软件环境)
winword——新建Office Word(必须安装Office办公软件)
excel——新建Office Excel(必须安装Office办公软件)
powerpnt——新建Office PowerPoint(必须安装Office办公软件)
其实DOS下的命令不止以上所介绍的,个人阅历有限,只列出了自己所知道的比较常用的DOS命令,对于其他的命令希望大家踊跃补充。
前面整理了MS-DOS常用命令,为什么先整理DOS命令,因为DOS命令是批处理的基础,只有打好基础才能进入下一步的学习。闲话少撤,下面步入正题。
批处理(Batch)是一种实现批量处理操作的脚本文件,通常说的批处理有两类:DOS批处理和PS批处理,其中DOS批处理就只我们接下来将到的,PS批处理是基于PhotoShop图片编辑软件的一种批处理图片处理的脚本。我们这里讲到的是DOS批处理,与PS批处理没有半毛钱的关系。
在Windows系统中,批处理可以称为一种基于DOS操作系统的简单脚本语言,实质它是有一系列(一个或多个)DOS命令组成的一个文件;主要用于实现自动批量的执行DOS命令而设计的。在Windows中通常将脚本称为宏,宏就是一系列命令组织在一起作为一个单独的命令来完成某一项任务。通过查看命令行工具的可执行程序,可以知道,批处理的脚本文件可以是“.bat”、“.exe”、“.com”、“.cmd”作为扩展名的文件,大多数情况下我们遇到的批处理是一个“.bat”文件。
学习什么,虽然都是慢慢体会其特点,但是我还是先将批处理的特点列出来,作为参照标准。上面介绍批处理实质就是一个或多个DOS命令组成的一个文件,所以在编写批处理脚本时,它的特点与MS-DOS命令特定基本一致。
批处理由MS-DOS命令行组成,用于实现文件、目录、文本文件内容等的批量处理操作。
批处理中的命令、命令选项以及参数是不区分大小写的,但是某些特殊情况下参数(主要指字符串常量)是区分大小写的。
批处理中的代码行使用换行符(包括Enter键等)进行分割或结束;一句代码的命令、选项以及参数等符号之间使用空白符(包括Tab键、Space键等)或其他特殊符号(包括“,”、“=”或“;”等)进行分割。
批处理的解析执行是按照从代码开始到结束的顺序执行的,也就是“自上而下”的顺序,哪条代码先出现就先解析执行,然后继续向后执行。
批处理值执行过程中,当遇到错误代码行时会捕获错误信息并进行向下执行,直到越多终止符为止。也就是说当遇到错误是不会回滚错位代码行之前的操作,同时会进行执行错误代码行之后的代码。
任何编程语言所支持的类型无非就三种:数字、字符和逻辑值。数字可以衍生为整数以及浮点数、字符可以衍生为字符串。MS-DOS操作系统作为最早的磁盘操作系统,估计没有考虑到数据的运算,而只是单纯的实现文件或目录的管理功能。所以对应批处理来说只支持整数数字和字符(串)两种类型。
在任何编程语言中,数值的表示都是有一定范围的,在批处理中数值的表示范围一般受限于处理器的位长,对32位的机器来说,整数值的表示范围为0x80000000h~0x7FFFFFFFh,即-2147483648~+2147483647。大多数情况下我们使用的都是十进制的数值表示法,由0~9这10个数字组成的值,同时批处理还支持八进制和十六进制的标识符,其中八进制以“0”为前缀,由0~7这8个数字组成的值,例如010表示十进制的8;十六进制以“0x”为前缀,由0~9这10个数字和A、B、C、D、E、F这6个字母组成的数值,例如0xA表示十进制的10。(进制表示法其实是数学知识)
对于字符来说,字符就是自然界中你所能想到并能描述出来的单个符号,字符一般与编码格式联系的比较紧密,何为编码格式,说白了就是将符号使用二进制的方式表示的标准(现在的编码格式比较多,需要了解的请自行查资料,常见的就是ASCII和Unicode两种字符集编码规范)。对应MS-DOS来说,初期的DOS基本只支持ASCII字符,也就是英文状态下的符号;由于需要国际化,所以现在基本都支持Unicode字符,也就是各国的字符符号。字符串,简单的理解就是有一个或多个字符组成的一段文字,批处理中可以直接支持字符串的表示,例如“ABC”可以直接使用,而在某些特定的情况下,字符串需要做一个特殊的处理,最常见的特殊处理方式就是使用英文状态下的“""”或“''”将字符串引起来;例如当在处理一个带有空白符的目录时可能会使用到,当在进行字符串比较的时候也可能使用到。
关于批处理的特殊符号的整理,我感觉有些纠结,因为特殊符号与批处理语句联系的非常紧密,单独的来说符号,估计你也不知道怎么用,所以这个地方将集合批处理语句来解释各个特殊符号的使用方式。
批处理中的特殊符号用于支持批处理程序的解析执行,这些符号属于批处理中保留的字符(串),具有特定的表示意思,在批处理中常见的特殊符号见下表。
在批处理中“@”符号一般用在命令去,用于屏蔽MS-DOS解析器对该命令的回显输出功能。默认情况下MS-DOS在执行批处理脚本是会将一行行命令显示输出到MS-DOS解释器的控制台,然后再执行。这个问题怎么理解?可以这样看,在命令行中输入DOS命令然后键入回车键,即可以执行输入的命令语句,由于MS-DOS解释器换行符的限定,所以我们不能在MS-DOS解释器中输入多行命令语句,只能单行单行的输入执行,然后再输入执行……为了解决这个弱点,可以将多条命令放在一起解释执行,于是批处理脚本就诞生了。
那么我们来看看批处理脚本是如何解释执行的,首先我们知道批处理是顺序解释执行的,也就是从脚本的开始第一行命令开始进行执行,一直到脚本的结尾最后一行命令。实质上MS-DOS解释器会读取每一行命令,然后执行,就相当于上面讲到的命令行命令的执行一样,首先输入命令然后按回车键执行,只不过这里是从批处理文件中读取一行内容然后输入到MS-DOS解释器,紧接着自动键入回车键进行执行,然后在读取下一行内容……,所以也就出现了在MS-DOS解释器中显示行内容的过程。因此批处理中提供了“@”符号来屏蔽回显输出的过程。用法比较简单:
@命令
“@”只是一个用于修饰命令的符号,所以命令的用法并不会受到“@”符号的影响,意思就是说命令该怎么还是怎么用。需要注意的是“@”符号只对使用“@”符号的命令起到回显屏蔽的操作,不对其后的命令语句起作用。下面我们可以使用文本新建一个bat文件测试一下(新建记事本,修改扩展名为bat确定即可),写入:
保存后,双击执行;然后在修改为:
保存后,双击执行,可以通过对比发现“@”符号的具体作用。
“>”和“>>”称为输出重定向符号,通俗一点的理解就是可以将内容输出到指定的设备或文件。通常这两个符号与命令一起使用,用于将命令的响应信息即执行命令的结果输出到指定的文件中,对于MS-DOS命令行来说,执行任何一个命令都会有对应的输出信息,默认情况下,这个输出的内容会显示在MS-DOS解释器的控制台中,当然这种情况是不便于查看的,因此批处理中提供了“>”和“>>”重定向符号来将内容输出到指定的地方。用法比较简单:
命令 ... > 文件地址
命令 ... >> 文件地址
与“@”符号一样,“>”和“>>”符号不会影响命令本身的用法,只不过右边必须要指定保存输出内容的文件地址,可以是文件的相对路径,也可以是文件的绝对路径,默认为相对路径,同时执行快磁盘分区输出。
为什么会提供两种输出重定向的符号?理所当然,两种重定向符号的作用必定不同,其中“>”符号用于将输出内容写入到一个空的文件中,也就是说文件的内容为空,当文件内容不为空时会首先擦除文件内容,然后在写入输出内容;“>>”符号用于将输入内容追加到指定的文件中,文件内容可以是空,也可以是非空的;两者的共同点就是在文件不存在时会自动新建文件。简单的理解就是“>”为写入新内容,而“>>”为追加内容,怎么将都是空话,只有亲自体验到了才能体会到。例如在新建的bat文件中输入以下代码:
“<”称为输入重定向符号,通俗的理解就是可以从指定的文件中读取一行内容到当前位置。通常与命令结合使用,用于从文件中读取一行内容作为命令的参数使用,而对于MS-DOS中任何一个具有输入参数的命令来说,默认是从MS-DOS解释器中接收输入信息的,当然这样就不够灵活,不能维护代码的完整性,所以就出现了“<”符号。用法相对比较简单:
命令 ... < 文件地
“|”称为管道符,作用就是将符号前的输出内容作为符号后的输入内容,之前我们遇到过“type ... |more”的写法,其作用就是将“type ...”命令行的输出内容作为“more”命令的输入内容,“type ...”用于查看文件内容,“more”用于分页显示,所以就实现类文件内容的分页显示功能。“|”管道符的用法相对严格一点:
命令1 ... | 命令2 ...
“|”符号一般需要两个命令参数,符号前的命令作为输出内容的命令,一般必须要有内容输入,符号后的命令作为接收输入内容的命令;即将命令1的输出内容作为命令2的输入参数。下面我们通过例子来理解。
其中“del /p”用于删除文件并在删除之前提示确认,当输入“y”则删除,输入其他则不删除。上面的代码是说将“y”作为“del /p”的输入内容进行处理。
可以看成“|”符号和“<”符号都可以实现输入内容的重定向操作,不过“|”是从命令行控制台的上一个命令输入信息中获取内容,而“<”是从一个特定的文件中获取内容的第一行信息。
“^”是批处理中通用的转义字符,可以将特殊符号转化为一般符号进行处理。当我们要输出“>”文本字符时,该如何处理?直接使用会将“>”符号作为重定向符号进行处理,这时就需要使用转义字符。转义字符的使用比较简单:
^特殊字符
这里所说的特殊字符一般指“|”、“&”、“<”、“>”这四个符号。例如:
“$”转义符号是“prompt”命令中的转义字符,通常后面接一个特定的字母表示一个结果。可以使用“prompt/?”或“help prompt”命令来查看使用说明。在这里就不多讲了。
批处理中提供了三种逻辑命令符:“&”、“&&”和“||”。三个逻辑命令符的作为分别为:
“&”符号——无条件执行符号后的命令语句。也就是符号后的语句一定会执行,这个符号大多用于命令的连接执行,即默认情况下MS-DOS只能解析一行的命令执行(以换行符为分隔符),通常情况下一条命令作为一行语句;可以使用“&”符号将多条命令连接起来执行达到一行书写多条命令的效果。
“&&”符号——只有当符号前面的命令执行成功时才会执行符号后面的命令语句,否则符号后的命令语句不会执行。
“||”符号——只有当符号前面的命令执行失败时才会执行符号后面的命令语句,否则符号后的命令语句不会执行。
三个运算符都必须两条命令语句参与,基本上都是由符号前的语句来决定符号后的语句是否执行。用法类是“|”管道符号,可以自行尝试练习。
通配符是一种特殊的符号,可用于模糊搜索,当我们不确定文件名称时可以使用通配符来代替符合标准的文件名。批处理中提供两种通配符“*”和“?”。在当我面不确定内容的时候可以使用通配符代替一个或多个或所有字符,其中“*”用于表示一个或多个任意字符串,而“?”用于表示一个任意字符。例如:
这里所说的引用符,主要是指在批处理中对环境变量以及参数信息的应用。也就是说使用这种符号标识的字符会被解析为一种变量,从而引用变量对应的值,当然这里说是引用,不是很确切,实质是一种特殊字符的替换方式。
“%”是比较灵活的引用符号,常见的基本有三种用法:使用“%xxx%”引用普通的非延迟环境变量扩展环境下的环境变量;使用“%number”引用特殊命令中的参数值,使用0-9表示参数的索引,即number的值是0-9之间的整数;作为字符“%”的转义字符,例如“%%”表示一个“%”字符,“%%%%”表示两个“%”字符。三种用法的标准格式为:
%变量名%
%参数索引
%%...
默认情况下,MS-DOS解释器在执行到“%xxx%”字符串的时候会将两个“%”之间的字符表达式“xxx”解析为变量名,然后在环境变量中查找该变量名对应的值来替换“%xxx%”字符串,从而达到引用变量的效果。同理,当执行到“%number”的表达式时,会自动查找对应索引的参数值来替换“%number”字符串,默认情况下%0用于表示当前执行的批处理文件的绝对路径。
“!”符号是对变量引用符号“%”的一个扩展,这个符号只有在开启了延迟环境变量扩展功能后才能使用,也就是出现在“setlocal”和“endlocal”之间。在延迟环境变量扩展环境中与“%”引用变量的方式一样,使用“!xxx!”的方式来引用环境变量,用法如下:
!变量名!
在延迟环境变量环境下,当MS-DOS解释器执行到“!xxx!”字符串的时候会将两个“!”之间的字符表达式“xxx”解析为变量名,然后在环境变量中查找该变量名对应的值来替换“!xxx!”字符串,从而达到引用变量的效果;当然,它没有参数引用和字符转义的功能。至于为什么会有这个符号的扩展,将在以后讲到。
上面已经讲到批处理支持数值类型的表示,同样支持数值类型的运算处理,当然批处理比较弱智,只支持整数类型的数值的算术运算,不仅支持基本的数学算术运算,还支持高级的算术运算。批处理支持的所有的算术运算符号如下表:
上面所列出来的就是批处理中所支持的算术操作符,只有在算术操作环境下才能被视为算术操作符,否则视为字符进行处理。在混合运算中,符号参与运算的顺序为:分组>一元运算>算术运算>逻辑运算>赋值运算>其他;其中元素分组元素内的符号运算顺序基本为乘除模优选,加减其次。这里值得注意的是“&”、“^”、“|”、“>>”、“<<”,这些符号在字符中有着特殊的意思,所以必须使用转义字符(“^”)进行转义才可以使用。具体怎么使用,后面会提到。
感觉这一篇介绍的主要是批处理的符号,就占用了这么多文字,可见批处理的确是有存在的意义的,所以了解批处理也是有所必要的,下一篇将介绍批处理命令语句的使用,如果将命令语句放到这一篇一起讲就太多了,不宜查看,所以于心不忍而又不得已,希望大家原理。
本篇紧接上一篇继续探索批处理脚本,上一篇主要介绍了批处理所支持的数据类型以及批处理中常见的符号所表示的意义,这一篇则介绍批处理的常见命令语句的使用方式。闲话少说,直入正题。
任何程序设计语言除了提供数据类型的支持、特殊符号的操作处理支持,当然还需要提供分支、循环、跳转语句的支持才能算的上是完善的语言。批处理的数据类型和特殊符号在上一篇已经介绍过,下面看看批处理中支持的分支语句、循环语句、跳转语句和其他控制语句。
批处理内置环境变量包括Windows的系统环境变量等,以下只是介绍接个在批处理中常用的批处理环境变量,至于批处理中引用Windows环境变量的用法与引用自身内置变量一样,关于Windows环境变量可以自行查看资料。
“cd”是MS-DOS目录切换的命令,当然它也是MS-DOS提供的内部环境变量,用于引用当前批处理脚本的工作目录完全路径名;其实与无参数的“cd”命令的返回结果一样,当作为环境变量引用的时候比较方便,可以直接使用“%cd%”表示当前工作目录。
“date”是MS-DOS提供的日期管理命令,同时也是MS-DOS提供的内部环境变量,用于表示当前系统日期,在Windows中通常与右下角日期格式一致。在批处理中可以直接使用“%date%”获取当前系统日期。
“time”是MS-DOS提供的时间管理命令,与“date”命令一样也是MS-DOS的内部环境变量,用于表示当前系统时间,在Windows中通常与右下角时间格式一致。在批处理中可以直接使用“%time%”获取当前系统时间。
“random”是MS-DOS提供的随机数内部环境变量,该变量返回的是一个0~32767之间的随机十进制数值。所以当我们需要使用随机数的时候可以直接使用“%random%”来获取。
“errorlevel”可译为“错误级别”,是MS-DOS(批处理)内置的用于监听某些语句执行成功与否的变量。可以将它看作批处理中某一句代码的返回值,它的结果是一个数值类型的代码,每一个代码都表示一种错误级别;它与每一条语句进行绑定,也就是说每一条语句都会返回一个错误级别代码并赋值给“errorlevel”变量,当然也有例外的情况,除过“pause”,“cls”,“set”,“echo”,“rem”,“path”,“title”等命令语句外大部分的文件和目录处理命令行都会返回错误级别代码。至于哪些语句可以返回、哪些语句不返回可以自己测试看看。
当某一条语句执行成功时将返回“0”,即“errorlevel”等于“0”时表示语句执行成功;如果执行失败则返回对应的代码,也就是说如果“errorlevel”为非“0”的结果都可以视为上一句代码执行失败。也就是说如果返回了错误级别代码就会直接赋值给“errorlevel”变量,之前的值就被覆盖了,如果没有覆盖就说明该条语句没有返回错误级别代码。
从上面的介绍可以得知,单单凭借“errorlevel”变量来获取某条语句执行结果是不准确的,因为部分语句是没有错误级别代码返回的,所以我们可以知道当“errorlevel”变量的值不为“0”时就代表某处语句发送了错误。“errorlevel”变量可以与“if”条件语句一起使用来进行判断。
“cmdextversion”可译为“CMD扩展版本号”,是MS-DOS提供的命令行扩展版本号常量,它一般与MS-DOS发行版本有关,第一个版本的时候改变量的值为“1”,每次对命令扩展名有相当大的增强时,版本号会增加一个。需要注意的是只有当命令扩展名被启用的时候才存在变量“cmdextversion”。
常常使用“cmdextversion”来检测命令行环境,例如在第二个版本中新增了一个扩展,则在第一个版本中是无法使用的,需要在执行前检查版本是否为“2”,如果是则可以成功执行,否则无法执行。实质该变量几乎用不到。
“cmdcmdline”可译为“CMD命令行”,是MS-DOS提供的命令处理器命令行引用的常量,它一般返回的是MS-DOS执行解释器的完全路径名。
“path”可以理解为“执行路径”,当指定一个程序名称后会首先在“path”指定的执行路径目录中进行程序搜索,如果搜索到则执行。“path”也可以是一个命令,同时也是一个内置变量,可以通过“%path%”来引用当前批处理程序的执行路径信息,默认为Windows系统环境变量中的“path”变量值。
“pause”命令用于暂停当前批处理程序的执行,并不是终止,只是暂时的停止执行并可以及时恢复执行过程。我们进程会见到一个批处理执行完成后必须按一下键盘,才能退出批处理程序,这就是使用了“pause”的效果。当执行到“pause”默认的会在批处理控制台显示“请按任意键继续...”字样,当按下任意键时则恢复,继续执行批处理程序。大多数的情况下都会使用到该命令,用法如下:
pause [...]
没有任何参数的“pause”命令的实质就是输出“请按任意键继续...”并监听按键事件触发,当触发按键后则终止暂停。
默认情况下,批处理文件一次执行完毕后就自动退出,就是我们看到的大多数情况下“一闪而过”的情况,如果我们想在批处理控制台输出什么信息则都无法查阅;现在就可以使用“pause”命令在批处理执行完成退出之前进行批处理程序的暂停操作,则就可以保留MS-DOS解释器的窗口,从而查看MS-DOS的控制台信息。我们来分析一下的代码:
保存为“.bat”文件后执行可以看出,第一条语句执行的结果为“请按任意键继续...”并等待按下任意键;第二条语句执行的结果为什么也没有输出,而是在当前工作目录中新建了一个名为“a”的文件,内容是“请按任意键继续...”,同时等待按下任意键;第三条语句执行的结果是没有输出内容和新建“nul”文件并等待按下任意键。来分析一下代码,“>”用于将命令的执行响应信息输出到指定的文件,所以“pause > a”会将“请按任意键继续...”输出到名为“a”的文件中,那么为什么“pause > nul”没有输出到文件呢?
“nul”是一个特殊的字符串,在批处理中它表示“空字符”,它是一个概念上的空字符,表示没有值,不是我们所说的空白符。上面的例子中的“pause > nul”意思就是说输出空内容,所以即不输出内容,也不输出到文件。也就是说,我们可以使用“pause > nul”来取消“pause”命令的输出内容。
关于批处理的回显问题,在上一节已经讲到过,“回显”就是打印要执行的命令语句,也就是每执行一条命令语句,都会先打印出来,然后在执行,当然这样查看程序执行过程比较混乱,所以大多数情况下需要关闭回显功能。上一节提到了“@”符号作为命令的前缀用于关闭该命令的回显功能,如果要关闭所有的命令回显功能,则需要在每一个命令前加上“@”符号,比较繁琐,下面就来介绍一种简单的处理方式——“echo”命令语句。
“echo”命令语句在批处理中,有两个作用:其一就是控制当前批处理程序的回显打开或关闭的状态设置,其二就是在MS-DOS解释器控制台输出信息。第二种作用前面已经用到很多次了,可以自行尝试一下。下面来看看使用方式:
echo [ON | OFF]
echo 信息
echo符号 [ON | OFF | 信息]
首先来看第一种方式,演变为“echo”、“echo on”或“echo off”三种方式,其中无参数的“echo”命令用于查看当前“echo”状态(即回显状态),默认情况下是开启的;“echo on”命令可以开启回显;“echo off”命令用于关闭回显,“echo off”的关闭可以适用与当前批处理程序,如果没有显示打开,即使用“echo on”命令,则当前批处理的回显状态一直处于关闭状体,所以我们可以使用“echo off”来代替繁琐的“@”命令回显屏蔽符号。例如我们最常用的两种方式:
第一种方式我们调用了“echo off”命令关闭了当前批处理的回显状态,而“echo off”命令在执行前,回显是开启的,所以使用“cls”来清空屏幕内容;第二种发送直接使用“@”符号屏蔽“echo”命令的回显功能;从而达到关闭所有回显状态。关于回显状体的设置,我们通常都在批处理的开头设定,因为这样比较合理,所以建议使用“@echo off”命令。
再来看第二种方式“echo 信息”,可想而知用于在控制台输出“信息”,其实这个信息就是你要输出的字符串,这种方式比较容易理解。要输出的内容紧接“echo”命令之后,注意必须使用空白符进行分割。我们来看下面的例子
保存为批处理文件并执行,可以看成在控制台只输出了“Hello World!”信息,没有其他信息,可以看出“@echo off”关闭回显功能已经起效。
最后看第三种方式“echo符号[信息]”,为什么会多出一个“符号”呢?首先看看我们如何输出“off”和“on”字符,可见使用第二种方式执行后实质就是第一种方式设置回显状态的命令,根本达不到输出“off”或“on”的目的。所以批处理提供了一种特殊的方式来输出像“off”或“on”这样的特殊命令字符,使用“echo+符号+字符”的方式来输出。例如:
保存为批处理文件并执行,输出的内容为:
off
(空行)
msg
上面的例子中,我们使用了特殊符号“.”,从例子可以看出无信息的“echo.”表示的是输出一个空白行,有信息的“echo.信息”命令等同于“echo 信息”输出信息用法。
事实上,批处理输出空白行的方式有多种,都是使用“echo特殊符号”的方式输出。当特殊符号后紧接特殊命令字符的时候,特殊符号用于将特殊命令字符转义为普通字符;当特殊符号后紧接普通字符是直接输出,类是于“echo 普通字符”方式。批处理中对“echo”命令提供的“特殊符号”有数十种,也就是说输出空行的命令有多种方式。其中提供的特殊符号包括“=”、“,”、“;”、“+”、“/”、“[”、“]”、“:”、“.”、“\”,使用“echo”集合任何一种特殊符号都可以输出空白行。
可以将上面的特殊符号分为三组,第一组有“=”、“,”、“;”,它们默认都是批处理中的特殊分隔符号,其实可以将分隔符看作命令参数或选项的一部分,通常批处理命令在执行带有分隔符的参数是会直接跳过第一个符号,也就是分隔符,而“echo”命令跳过分隔符后其后的字符为“NUL”,所以输出了空行,而当分割符为“空白符”时会跳过并解析其后的字符是否是命令参数;第二组有“+”、“/”、“[”、“]”,它们不是特殊的分隔符,所以会将其作为一个整体进行解析,但是“echo/”等又不是MS-DOS命令,所以会作为外部命令来搜索和执行,它们可以作为外部命令进行执行;第三组有“:”、“.”、“\”,既不是特殊分隔符,也不是外部命令,在执行的过程中,会尝试自动修复命令进行命令的修复转换,所以它们的效率是极低的。(信息来自“批处理技术内幕”介绍)
通过后面的简单介绍其实为了说明一定,从执行效率上来将,当使用“echo”命令输出空行时可以优选考虑使用“echo=”或“echo,”或“echo;”命令,上面所列车的三组符号中,每组的效率依次递减。
rem 注释说明信息
“注释说明信息”可以是任意文字,也可以是一条命令语句,被注释的语句和文字不参与解释执行。例如:
保存并执行的结果为输出一个空行,而“rem”后的“echo”语句并没有执行。
在批处理中还存在符号“::”与“rem”命令的作用一致,可用于语句的注释说明。用法与“rem”也一样,如下:
::注释说明信息
“::”是一个特殊符号,并发批处理脚本规范的注释命令,在批处理中使用“::”标注的语句或字符串,作为无效信息,在执行过程中将直接忽略;而“rem”标识则会解释为“rem”命令的作用。也就是说在作用上它们是相同的,但是在原理上就不同了。其实“::”用于弥补“rem”命令的某些不足存在的,在某些特殊的情况下,使用“rem”命令注释带有“>”、“<”、“>>”、“|”等特殊符号的时候不能达到预想的效果,但是可以使用“::”来进行注释。
变量,一般的编程语言中都存在这个名称,它表示一个可变的量,可以在程序中寄存一个数据项,并在其他的地方引用。从批处理支持的数据类型来看,批处理脚本中变量的类型应该有字符串和数值两种。讲到变量,就得提提变量的名称了,批处理脚本中对变量的名称没有做任何规定,可以是任意符号或字符串,当然也可以是数值,所以说批处理脚本是比较弱智的。
批处理中的变量主要使用“set”命令来维护和管理,而在批处理中的变量也称为环境变量。批处理规定的“set”命令用法比较多,主要有以下四种用法。
1.“set”命令查看变量
“set”命令可以用于查看变量信息,它返回的是所有符合的变量列表,格式为“变量名=值”。用法比较简单,如下:
set [变量名前缀]
这里“变量名前缀”的意思是指“set”命令会在所有变量中进行查找,如果某个变量名的前缀(从第一个字符开始到第N个字符)与所给定的变量字符串相匹配则将改变了视为要查找的变量,是一种前缀查找方式。当没有指定任何变量前缀时则列出所有的变量列表。
2.“set”命令管理字符串变量
“set”命令可以实现字符串变量的定义和删除等操作。用法比较简单,如下:
set 变量名=[值]
这里使用了一个“=”紧跟在变量名称后,表示定义一个变量并进行赋值,这里如果把“=”省略了则变为查看变量命令了。因此当需要定义变量的时候不可缺少“=”,“值”是可选项,当存在时则表示给当前变量赋值;如果不存在则表示删除当前变量,也就似乎给变量赋空值。可以参考下面的例子:
保存为批处理文件并执行,输出的内容为:
var=abc
var=
当给指定变量赋空值时表示移除该变量。
3.“set”命令管理数值变量和运算
“set”命令不仅可以管理字符串变量,同样可以管理数值类型的变量。批处理中使用“set /a”命令来实现数值的运算操作,“/a”是“set”的一个选项,表示其后的字符将被作为数值和算术操作符进行处理,如果不是数值将提示错误。用法如下:
set /a 数值表达式
这里的“数值表达式”不是一个固定的值,而是一种由数字和符号组成的任何一种算术表达式。表达式可以包含前面介绍的任意一种或多种“数值类型符号”,具体符号可以参考具体说明。例如,“set /a result=123+345”,则表示将“123+345”的计算结果赋值给“result”变量;而“set /a 123+345”在表示计算“123+345”的结果;同时还支持简单的位运算等,支持“()”优选运算,支持“,”多个表达式同时运算等特点。例如:
保存为批处理文件并执行,输出的内容为:
算术运算:1+2=3
字符串:1+2=1+2
从例子可以看出,如果要进行数值运算,必须使用“set”命令的“/a”选项来标明。
4.“set”命令实现控制台输入
下面来介绍“set”命令的另一个扩展功能,从控制台或其他设备或文件将信息读取一行字符串并赋值给指定的变量。使用“/p”选项来启用这个功能,用到的较多的地方就是读取从控制台输入的字符串。当解释器执行到“set /p”命令时会等待用户的输入完成,一般使用回车键表示输入完成;在输入过程中可以使用“CTRL+C”快捷键强制退出输入状态。用法如下:
set /p 变量名=[值]
只是在定义字符串变量的操作之前加上了“/p”选项,其中“/p”选项表示将启用控制台输入功能,并将输入的内容赋值给“/p”后指定的变量名,注意“=”不能缺少。当然也可以赋给变量初始值,但是当输入完成后变量将被重新赋值。例如:
保存为批处理文件后可以自行测试。
“cls”命令,在MS-DOS那一节已经讲过了,主要用于清除当前屏幕(包括当前语句)中的所有显示信息,当感觉屏幕内容较多或较混乱时可以使用,用法比较简单,它没有多余的选项。下面看一个例子,使用“cls”命令清除回显内容实现“@echo off”命令的效果:
“color”语句用于设置当前批处理MS-DOS控制台的前景(显示字体)和背景颜色,可以使用该命令来设置当前会话中别致的命令行窗口。用法如下:
color [前景颜色值[背景颜色值]]
“color”主要用于设置MS-DOS控制台颜色值,MS-DOS系统使用的十六进制的数值来表示16种颜色,数值与颜色描述表如下:
淡浅绿色
针对“color”语句来说,无参数的“color”语句可以将当前MS-DOS控制点前景和背景颜色还原为默认值,默认前景为白色字体,背景为黑色;对于有参数的“color”语句,第一个颜色值表示前景颜色,第二个颜色值表示背景颜色;如果只有一个值则表示设置前景颜色,也就是显示文本颜色。
有一点需要注意的是,如果前景和背景颜色值相同时会导致颜色冲突,所以MS-DOS会将“errorlevel”错误级别设置为1,表示设置颜色异常;也即是说MS-DOS不允许前景和背景颜色设置为同一个颜色值。
“title”命令语句用于设置当前执行批处理命令提示窗口的窗口标题,和“color”命令差不多都用于设置批处理程序的。当需要自定义命令行窗口标题是可以使用该命令实现。用法比较简单:
title 标题内容
1.分页查看控制台显示内容
当一个命令语句的响应信息较多时,可以使用“more”命令来实现分页查看的效果,常使用管道重定向符号“|”将命令行的输出信息作为“more”命令的输入信息进行处理。用法如下:
命令行语句 | more [more命令选项
从用法规则上看,“| more”命令作为某个命令语句的子语句,其中管道重定向符号“|”用于将命令行语句的输出信息作为“more”命令的输入内容进行处理,从而达到对命令行输出信息的分页查看效果。
2.分页查看文本文件内容
“more”命令不仅可以接收MS-DOS控制台的输出信息,同样可以接收MS-DOS从文件读取的信息,这种用法非常类似“type .. | more”命令查看文件内容的用法。用法如下:
more [more命令选项] [<] [files]
“more”命令可以替换“type”来实现文件内容的友好显示。其中输入重定向符号“<”是可选项,当然为了标准可以明确标识;当要查看的文件未指定时,则接下来的输入信息将作为查看的内容,如果要同时查看多个文件,则文件名需要使用空白符分割,实质是将文件内容拼接后显示的。
“more”命提供丰富的处理选项,可以通过“more/?”或者“help more”命令来查看,其中“/C”选项可以在显示下一页内容前清除屏幕信息;“/S”选项可以将多个空白行缩为一行进行显示;“/E”选项可以启用“more”名的扩展功能,从而实现对子命令的支持,例如可以通过“S n”子命令来跳过下一页的n行信息等,具体说明可以查看使用说明。
“if”语句是批处理中的条件分支语句,表示的意思就是“如果...则...否则...”,大多用在批处理程序中的条件处理部分。“if”语句在批处理中使用的是比较广泛的,例如要查看某个文件,则首先要确定该文件存在才可以查看,否则MS-DOS会抛出错误信息,这个时候就可以使用“if”语句进行判断。“if”命令语句是通过条件成立与否来决定语句的执行,这里的条件成立和条件不成立可以理解为“true”和“false”,但是批处理中不存在这两个常量。“if”语句所表达的意思是只有当条件成立时才会执行指定的命令语句,主要有以下几种用法。
1.判断信息是否相等(“==”)
“if”命令语句就是用于条件的判断,然而由于批处理脚本本身比较弱化,所以初始的MS-DOS只能支持信息相等的比较,也就是只支持“==”操作符。用于比较字符串与字符串、变量与变量、变量与字符串之间是否相等,如果相等则表示条件成立。用法如下:
if [not] 信息比较表达式 (
命令行1
) else (
命令行2
这里的“信息比较表达式”的格式为“字符串1==字符串2”或“变量1==变量2”或“变量==字符串”的形式,也即是说只能使用“==”进行字符串或变量之间的比较,上面的“not”表示相反操作,不做多的解释,来看下面的例子:
保存为批处理文件,执行既可以看到效果,可以自行修改,添加“not”试试。
2.判断错误级别信息
错误级别“errorlevel”是MS-DOS的内置环境变量,在上面已经介绍过,主要用于保存上一条命令语句是否执行成功,成功则返回0,失败或错误则返回相对应的错误级别码。然而“errorlevel”是内置环境变量,所以可以使用下面的方式判断:
然而“if”语句提供了一种特殊的错误级别判断方式,如下:
if [not] errorlevel number (
命令行1
) else (
命令行2
这种方式并不是使用变量的方式进行引用,而是作为关键字使用,“number”表示一个错误级别码,“not”表示相反操作,不做多的解释。使用这种方式比较简洁。
3.判断文件是否存在
在上面已经提到关于文件是否存在的判断,“if”语句提供了一种特殊的文件判断方案,用法如下:
if [not] exist filepath (
命令行1
) else (
命令行2
其中“exist”是关键字表示“存在”,“filepath”表示要判断的文件路径,如果检查到指定的文件存在则执行对应的命令块,“not”表示相反操作,不做多的解释。多说无益,直接看例子:
4.判断MS-DOS扩展版本号(扩展用法)
MS-DOS扩展版本号“cmdextversion”是MS-DOS的内置环境变量,在上面已经介绍过,当在使用某个新扩展特征时可以首先判断版本号是否对应,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的,进行扩展版本号判断是“if”语句的扩展用法。用法如下:
if cmdextversion number (
命令行1
) else (
命令行2
意思是说当当前批处理扩展版本号与给定的“number”值对应时执行“语句1”否则执行“语句2”,大多数情况下不会使用这个命令语句。
5.判断变量是否存在(扩展用法)
变量是否存在的检查是“if”语句的扩展用法,用法比较广,可以判断变量是否被声明,然后在斟酌使用,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的,用法比较类似文件是否存在的判断用法,如下:
if defined 变量名 (
命令行1
) else (
命令行2
6.信息比较运算(扩展用法)
上面介绍过“if”默认情况下只支持相等比较运算,然后后续考虑则对“if”语句进行了命令扩展,使其可以支持多种比较运算操作,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的。用法与“if”相等比较运算的用法一致,如下:
if [/i] 操作数1 比较运算符 操作数2 (
命令行1
) else (
命令行2
其中操作数可以是字符串也可以是数值,同时还可以是变量;“/I”选项用于开启比较过程中字符串大小写忽略功能;在命令扩展下支持的比较运算符有:“equ(等于)”、“neq(不等于)”、“lss(小于)”、“leq(小于等于)”、“gtr(大于)”、“geq(大于等于)”六种,其中“lss”、“leq”、“gtr”和“geq”四种比较操作符主要用于对数值进行比较,当参与比较的字符串是字符串时,将被转换为对于的ASCII码进行比较;而“equ”和“neq”既可以比较数值也可以比较字符串。来看下面的例子:
上面的例子可以说明“/I”的用法,以及其他命令扩展下的操作符用法,保存为批处理文件即可执行查看效果。
综上所述,特别提示以上的“if”语句中的“else”子句是可省略的,“else”只是起到多分支的作用,表示当条件不成立时执行的处理过程,不必要时可以去掉。关于“()”表示范围,用于表示多条语句执行的语句块(批处理中的每一条语句都是以换行符作为结束符号的),也就是说当条件成立是会执行“if”后“()”内的所有语句,当只有一条语句需要执行时可以省略“()”,特别需要注意的是省略“()”时,命令和“if”语句必须写在一行,当有“else”子句时必须使用“()”。【小提示:注意“()”与关键字之间的空格】
前面已经介绍过变量的引用原理,就是查找变量名对应的值来替换“%变量名%”字符串,从而达到变量引用的效果,这个过程也称之为变量扩展过程,这种过程可用于处理基础的普通的变量,然而我们来看看下面的例子:
按照正常的执行流程可以推断出结果为“重置var的值成功[var=after]”,然而真实执行的结果并不是我们想象的,保存为批处理文件并执行输出的结果为“重置var的值失败[var=before]”。我们来看看为什么为出现这种情况?首先声明了变量var的值为before,紧接着为一个“if”语句,又在“if”语句中对变量var进行重新赋值,然后在进行判断,然而该程序在解释执行的过程中,将“if”语句以及其内的“set”命令和“if”语句作为一整条语句进行解释的,当遇到“%var%”时会自动查找“var”的值替换当前语句,也就是整个外层“if”语句中的所有“%var%”字符串,因此内部的“if”判断条件中的“%var%”被替换成了“before”,所以永远都不会与“after”相等。这就是变量扩展的过程,那么外层“if”语句中的“set var=after”是否执行了呢?答案是肯定的,通过在程序末尾追加“echo var=%var%”可以看出。
通过上面的例子,可以得出一个结论就是批处理中的默认变量替换过程值针对一整条语句的,也就是说如果一整条语句中某个地方有变量的引用,则将会影响到该条语句中的所有变量引用,同一条语句中的所有变量引用会在同一时刻被替换为该变量对应的值。通俗的说,就是默认情况下,一条语句中的变量的值是固定的。
针对这个现象,批处理提出了延迟环境变量(简称延迟变量)的概念,主要用于对变量进行扩展,弥补普通变量的应用过程中的不足,通过延迟环境变量可以实现在一整条语句中改变变量的值。也就是说可以通过延迟环境变量概念来实现子句内部的变量声明、定义和赋值等操作。批处理中给出了“setlocal”和“endlocal”命令来实现延迟变量扩展功能的开启和关闭操作,来看看两个命令的用法:
setlocal enableExtensions | disableExtensions
setlocal enableDelayedExpansion | disableDelayedExpansion
endlocal
“setlocal”命令有两种用法,第一种用法用于启动(enableExtensions)或者停用(disableExtensions)命令处理器扩展名功能,这个用法主要用于管理MS-DOS解释器的命令扩展功能,默认是开启的,一般很少用到;第二种用法就是现在介绍的用于启动(enableDelayedExpansion)或者停用(disableDelayedExpansion)延迟环境变量扩展功能,默认是停用的。“endlocal”命令用法比较简单,就一个单一的命令行,该命令行主要用于停用延迟环境变量扩展功能,命令执行后将会还原当前批处理的扩展功能为默认值,所做的环境变量的改动不在局限于当前批处理文件;实质上“endlocal”比较特殊,是可以省略的,也不是一定要与“setlocal”成对出现,当一个或多个“setlocal”没有强制使用“endlocal”时会在批处理文件的末尾自动执行“endlocal”命令来还原初始默认设置。
当开启延迟环境变量的扩展功能后,对环境变量的修改和引用将会扩展到整个批处理程序中。下面来看看如何使用延迟环境变量的扩展功能?现在使用延迟环境变量扩展功能解决上面遇到的问题,代码如下:
在这段代码中,首先使用“setlocal enableDelayedExpansion”语句启用了延迟环境变量扩展功能,保存为批处理文件并执行的结果则为预想的效果“重置var的值成功[var=after]”,代码中并没有强制使用“endlocal”语句停用延迟环境变量扩展功能,但是MS-DOS解释器会在程序的末尾,也就是“pause>nul”语句之后自动调用“endlocal”命令重置MS-DOS环境默认值。
但是上面的代码与之前的代码还有一处细小的区别,就是这里使用了“!xxx!”的方式来引用变量。然而为什么要使用这种方式呢?“%xxx%”的方式是否可行?答案可想而知“%xxx%”的方式肯定不可行。之前已经介绍过“%xxx%”方式的变量替换原则,当在一条命令的整体语句中时,如果首次遇到“%xxx%”的字符串,则会自动查找并替换该整条语句中的所有“%xxx%”字符串为指定变量的值;正是这个原因,所以提出了延迟环境变量扩展的概念,延迟环境变量扩展就是为了解决整条语句中所有变量被替换的问题,然而在提出延迟环境变量扩展概念的同时扩展了“!xxx!”的变量引用方式,主要用于区别默认的“%xxx%”变量引用方式,而且“!xxx!”变量引用方式只能在延迟环境变量扩展功能开启的环境中才能被解析。
来总结以下,关于延迟环境变量扩展的用法,延迟环境变量扩展功能主要用于解决像“if”、“for”以及各种复合语句(使用逻辑运算符拼接的语句)等中,用于在语句内部引用修改后的变量,因为默认情况下语句中的变量是被提前替换的,使用延迟环境变量则可以延迟替换过程到解析到该变量时;使用“setlocal enableDelayedExpansion”语句开启延迟环境变量扩展功能后,只能使用“!xxx!”的方式引用变量,表示该变量将被作为延迟环境变量进行处理,如果使用“%xxx%”方式引用将继续作为普通变量处理;开启延迟环境变量扩展功能后可以在必要的时候强制使用“endlocal”或“setlocal disableExtensions”语句停用该功能,默认在程序结尾自动调用“endlocal”语句进行重置。
对于一门程序语言,单单提供分支语句是不够的,必须还要提供循环语句才能满足重复执行某一项任务的需要。在批处理脚本程序中同样提供了循环语句——“for”语句,主要用于实现重复执行某一项命令,“for”语句设计由衷用于对一组文件中的每一个文件执行某项特定的命令操作,同时也可以扩展为对一个集合中的每一个元素执行某项特定的命令操作。“for”语句主要有一种基本用法和四种扩展用法,下面将一一介绍。
1.循环遍历元素(基本用法)
批处理中的循环主要用于遍历集合中的元素,语法结构如下:
for %%临时变量名 in (集合列表) do (
命令行
基本结构比较简单,使用“for...in...do”的方式,字面意思就是“把在集合中的所有元素都执行一遍操作”,使用这种方式将一个集合中的所有元素都执行一次相同的命令。
在循环遍历过程中如何取得每一个元素呢?在批处理中的循环语句中提供了一个临时变量用于保存每一个元素(不区分元素类型),从语法上可以看出“%%临时变量名”就是这个临时变量。这里的临时变量的声明与之前将的环境变量的声明不大一致,环境变量的声明直接使用“xxx”方式,而在“for”语句中的临时变量声明使用“%%xxx”方式。至于为什么这样规定,我也没有搞清楚,之前介绍过“%”有转义的作用,所以这里的第一个“%”可以看作为转义字符,正式的变量名为“%xxx”,或许是为了区分环境变量(语句外定义)或语句内变量。需要注意的是临时变量“%%xxx”中的“xxx”可以是任意字符,而且必须是单个字符,当为英文字母时其名称是区分大小写的,为什么只能为一个字符下面会通过例子介绍到。由于“%%xxx”格式的临时变量保存的是一个元素,所以可以直接在“for”语句内部使用“%%xxx”方式来访问该临时变量,这一点也与环境变量的访问方式不同。
关于集合列表中的值,可以是任意值,多个值使用英文状态的逗号(“,”)分割开来,而且集合无论有多少值都必须使用“()”括起来,表示一个集合范围。上面说过“for”语句的由衷就是为了遍历一组文件,所以不管集合列表中是什么值,都作为文件名来处理,无论该文件是否存在都会进行遍历,默认情况下只是作为文件名(字符串)进行处理,当然还可以进行更高级的扩展处理。也就是说,事实上看到的字符串,实质是作为文件名进行处理的,所以元素支持通配符“*”和“?”,“*”表示当前工作目录下的所有文件。多说无益,看下面的例子:
上面的例子用于变量所有的元素,其中1,3,5,7将作为文件名进行输出。保存为批处理文件并执行可以看看结果。
上面的例子用于变量每一个元素,其中“*”表示当前工作目录下的所有文件,并将文件名打印输出,保存为批处理文件执行即可看到效果。
上面的两个例子足以说明“for”语句的基本用法,其中如果要重复执行的语句为多条语句时必须使用“()”将多条语句括起来,与“if”基本相识;如果是单条语句可以直接写在“do”后面。
2.循环遍历目录(扩展用法)
批处理中的“for”语句默认是用于遍历文件列表的,如果想变量一个目录列表又该如何操作?在批处理的“for”语句结构中提供了一个“/D”选项,可以将集合列表中的元素值强制作为目录名称进行处理。语法结构如下:
for /D %%临时变量名 in (集合列表) do (
命令行
该用法只是在基本用法的基础上,多了一个“/D”选项用于修饰临时变量,主要是将临时变量的值进行目录检查,如果是目录则取用,否则则丢弃。看下面的例子,在C盘下的文件夹中存在文件和子文件夹:
通过上面的代码执行结果的对比可以看出“/d”选项的作用,用于匹配目录名称,忽略文件。
3.循环遍历指定工作目录下的文件或目录(扩展用法)
在第二个用法的例子中开头有一句“cd C:\test”将当前工作目录切换到C盘的test目录,如果不指定则默认工作目录就是当前批处理所在的目录,这样写虽然很直观当时相对比较麻烦。在批处理的“for”语句中提供一种指定工作目录的方式,使用“/R”进行工作目录的指定,用法如下:
for [/D] /R 工作目录 %%临时变量名 in (集合列表) do (
命令行
该用法是基础用法的扩展用法,可以直接在“for”语句内指定要查找的工作目录,使用“/R 工作目录”的方式指定。指定后将在当前“工作目录”中进行文件的查找遍历。当然可以与“/D”一起使用,用于查找变量目录,当与“/D”一起使用时“/D”修饰必须写在“/R 工作目录”的前面。下面我们来改写第二个用法中的例子,如下:
保存为批处理文件并执行则可以看到执行结果与第二个用法的基本一致,只不过这个用法输出的是文件或目录的完全路径名称,这是“/R”选项的另一个特点。如果你细心,还会发现“/R”选项还可以查找变量到目录下的子目录或子文件,如果我们在C:\test目录下的某一个目录下再添加一个文件或目录,则同样会打印输出。
来总结一下“/R 工作目录”的用法,可以查找当前工作目录下的所有文件或目录,包括子目录下的文件或目录,直到没有下一层为止;每一个临时变量保存的是文件或目录的完全路径名称。也就是说使用这种方式我们可以实现目录结构树图,可以自行尝试一下。再来看看上面讲到的两种用法,基础用法和“/D”选项用法只能查找当前工作目录下的文件或目录,而并不能进一步深入查找下一层文件或目录。
4.固定频率循环(扩展用法)
上面介绍的“for”语句主要用于文件管理中的循环遍历操作,这些循环操作执行的次数都是受到工作目录中文件或目录的数量的影响,是不固定的;当我们需要执行规定次数的某一个操作时,又该如何实现呢?当我们要迭加一个数值又该如何实现呢?其实在批处理的“for”语句中提供了“/L”选项,专门用于实现数值范围的遍历操作,用法如下:
for /L %%临时变量名 in (start,step,end) do (
命令行
从语法结构上看,添加了一个“/L”选项修饰操作,同时“集合列表”也固定了结构,是一个有start、step、end三个数值组成的列表,从语义上可以知道集合列表中的“start”表示循环的开始数值,“end”表示循环的结束数值,而“step”表示循环的递增频率数值;过程是第一次循环临时变量将被赋值为“start”指定的数值,之后每一次临时变量在原有值的基础上增加“step”指定的数值,然后与“end”指定的值进行比较是否小于等于,如果是则执行下一次循环,否则跳出循环。举个例子,如果我们要循环3次则列表集合可以写作“(1,1,3)”,就是说临时变量从1开始,到3结束,每一次循环后增加1;如果要打印输出10以内的奇数,则可以写作“(1,2,10)”。多说无益,来看下面的例子:
保存为批处理并执行既可以看到结果。“for”语句使用“/L”选项后,要求集合列表必须包含3个数值,其中第一个表示循环起始值,第二个表示循环频率值,第三个表示循环结束值,这些值必须是数值,而且可以为正负数值。
5.高级扩展应用
上面已经介绍了“for”循环的几种不同应用方式,但是不足以灵活多变,所以批处理还提供了高级扩展应用,包括文件内容循环遍历、内容查找处理操作、动态执行命令行等功能。高级扩展应用使用“/F”选项进行开启,用法如下:
for /F [操作选项] %%临时变量名 in (集合列表) do (
命令行
扩展用法与上面介绍的几种基本一致,不过这里在“/F”选项后包括一个“操作选项集合”,下面会介绍到。
首先来看看“集合列表”,集合列表可以是文件集合、字符串集合(我们知道文件都是扩展名的,或许可以简单的区分为文件名或字符串)或命令集合。当集合中的元素为一个或多个文件时,则在进入循环语句时,当前文件和之前已经遍历的文件都将处于打开状态,并接受读取等操作,处理包括读取文件行(将文件内容以换行符分割或空白符截断)并将每一行信息解析为一个或多个字符串(按操作语句指定进行解析分割),当为文件名时需要注意的是当文件名中有空格符号是需要使用“""”将文件名引用起来;当集合为一个或多个字符串时,必须使用“""”将字符串引用起来,则执行过程将会对每一个字符串进行一一处理;当集合类型为一个命令行语句时,命令行语句需要使用“''”括起来,则会对该命令行的响应输出信息进行处理。例如:
这个例子就是变量“echo HelloWorld!”命令语句的输出信息。
下面再来看看“操作选项”,这里的操作选项必须使用“""”括起来,可以包含一个处理选项或多个处理选项,多个处理选项之间使用空格符号进行分开,处理选项在该用法中是可选的。如果处理选项不存在,则临时变量表示的是每一个文件或字符串或命令输出的一行内容,这一行内容以空白符进行截断;如果处理选项存在,则临时变量表示的是每一个文件或字符串或命令输出的一行内容中符号条件的部分内容。处理选项包括一下几种(是一种子命令的方式):
上面列表所列的是“/F”选项下的所有操作选项说明,这些选项只有在“/F”选项下才可以使用。废话不多说了,看下面的例子:
“for”语句的“/F”选项扩展主要用于内容的循环查找操作,在查找过程中对应的临时变量的操作存在一个特殊的扩展处理方式——自动变量扩展,比如说当使用tokens操作选项来取得每一个元素或每一行的某个或几个字符时,可以自动以当前定义临时变量名(单独字母字符)为起点进行后续扩充,定义的临时变量保存取得的第一类字符信息,下一个字符扩展的临时变量则表示第二类字符信息,依次类推,规定最多只能扩充26个临时变量(包括当前变量在内),是由于tokens选项最多只能指定26个值集合。来看下面的例子:
这个例子是将“DIR”命令的输出信息作为遍历内容,首先跳过前两行,然后从第三个字符块开始取值,使用默认的方式进行换行或截断操作,其中第二个字符块将作为“%%a”的值,第三个字节块作为“%%b”的值,第三个之后的字节块作为“%%c”的值。(目前我还没找到什么特殊的规律,这个值只能靠查看结果才能知道所表示的内容是什么,临时变量扩展虽然很方便但是使用需要谨慎,如果没有取到值则会输出“%变量名”信息,我并没有很深入的去了解它,如果你有兴趣,可以深入了解并整理一下结论和规律分享给大家)
“goto”从字面上理解就是跳转的意思,“goto”语句就是批处理中提供的流程跳转语句,何为流程跳转?首先批处理的执行过程是自上而下顺序执行的,默认情况下,批处理文件中的所有语句都会执行,不论上一条语句是否执行成功。如果在执行过程中遇到某种情况需要进行特殊处理,那么就需要改变执行的流程,不过可以使用“if”语句来实现流程的控制,从理论上也可以实现跳过部分语句代码的过程,但是比较麻烦,需要使用“if”语句块来实现,所以批处理提供了“goto”语句来实现标签式流程跳转。标签式跳转也就是说首先要定义一个标记,然后使用“goto 标签”的方式跳转到指定的标签语句块内,所以“goto”语句必须结合标签实现执行流程的跳转,在批处理中使用“:”来声明标签,来看标签和“goto”语句的基本用法:
goto [:]标签名
: 标签名
命令行
批处理中规定,“goto”语句用于标签式跳转,其后紧接要跳转到的标签名称(中间使用空白符分割);标签的声明必须使用“:”作为前缀,也就是说在批处理中以“:”开头的字符串或语句都是标签,其标签后的命令行语句是该标签的标签体,只要没有遇到“goto”跳转语句则其后的语句都会执行;其实标签体是一个模糊的概念,很多情况下它是混淆的。看下面的例子:
上面的例子,从语法上看,定义有“a”标签、“b”标签和“end”标签,从执行流程上看,“a”标签和“b”标签是混淆的,因为缺少标签结束语句,所以在使用标签跳转的时候一定要为标签体定义一个“goto”语句,表示跳出标签体,如果是最后一个标签则可以忽略。
使用“goto”必须注意,标签体在必要的时候必须使用“goto”跳转语句进行终结,否则其后的所有标签或非标签都会作为当前标签的标签体进行执行,正如上例一样;其次还需要注意标签结束时的“goto”跳转语句,如果没有需要,最好不要跳转到当前标签,否则会构成“死循环”,不断的执行当前代码体,理论上是无法退出的。看先一个的例子:
从执行流程上分析,这段代码首先进入“start”标签,然后跳转到“start”标签,然后在进入“start”标签……从而构成了一个“封闭的回路”,会无穷的执行下去(这只是理论上的猜想,实际上当达到某一个次数后会自动停止)。因此没有必要这种写法是不可取的。最后,再来看一个例子,使用“if”和“goto”实现的简单计算器:
上面的例子中使用了一个“goto :eof”语句,从运行的流程上看,如果没有选择则会跳转到“eof”标签,从结果上看,实质是退出了批处理文件,为什么呢?因为“eof”标签是批处理中的默认标签,用于跳转到批处理文件的末尾,也就是最后一条语句的后,所以会直接退出批处理文件。这个地方不能直接使用“goto eof”,因为这样会默认将“eof”作为自定义标签进行处理,只能使用“goto :eof”方式。
“start”的字面意思是“启动”,无可异议在批处理中是用于启动程序的。“start”命令比较独特,可以启动人任意的程序或文件,只需要指定程序或文件的名称即可,可以是全名称(如果不指定扩展名会按照环境变量自行查找匹配),执行跨磁盘的程序启动。其实“start”命令是一个启动程序的入口,用法如下:
start ["title"] [/I] [/MIN] [/MAX] [/B] [command/program] [parameters]
其实“start”命令提供的选项操作比较多,可以通过“start/?”或“help start”命令查看,上面列出的是几个常见的选项操作。其中“command/program”表示命令或程序名称,“parameters”表示参数。
同时“start”命令还可以启动其它程序,包括可执行程序以及文件等,但是可能不会提供更多的选项操作。同样的道理,“start”命令是以要打开的程序所关联的默认执行程序打开当前程序或文件的。了解Windows系统应该知道文件关联选项中的一些设置,其实文件都是通过命令语句打开的。
“call”的字面意思是“调用”,在批处理中“call”命令用于实现批处理文件的调用操作,事实上它不仅能实现批处理文件的调用,还可以实现标签式调用,标签式调用与“goto”的用法非常相识。“call”命令的用法如下:
call 批处理文件路径 | :标签名 [参数]
“call”命令可以在当前批处理文件中调动另一个批处理文件,也可以在当前批处理文件中调用某个声明式标签,从作用可以知道“call”共兼了“start”和“goto”的作用,其实还是存在一定的区别的。
从这个简单的例子可以看成“call”命令的执行过程。其次“call”命令也具有调用其他可执行程序功能,与“start”命令使用一样。
下面看一下“call”命令标签跳转用法,使用“call”语句实现标签跳转语句与“goto”语句的用法非常类似,只需要在“call”命令后紧接要跳转的标签名称即可,唯一不同的是这里的标签名称需要指定“:”前缀,同样可以在标签名称后拼接多个执行参数,看下面的例子:
这个例子可以说明“call”语句不仅能实现“goto”语句的功能,同时还可以传递参数。实际上“call”命令调用预先定义的标签时,会将标签语句视为一个批处理程序集进行执行,执行完该标签的所有语句后会再次返回到“call”语句后继续执行,这也是“call”标签跳转与“goto”标签跳转的另一个区别,“goto”标签跳转后会继续向标签后执行,不会自动返回到“goto”语句后。通常情况下,使用“call”命令来调用标签语句时,标签体的末尾应该使用一个“goto :eof”语句来结束标签体,当然也可以使用其他的语句,这样做是为了可以编写多个“call”调用的标签体语句,避免混淆。
其次来看看关于“call”语句传递参数后如何访问,在之前介绍“%”的时候介绍过“%num”(0=<num<=9)方式可以用来引用某些特殊命令语句传入的参数,其中“num”表示参数的索引,从“0”开始,所以上面我们使用“%0”、“%1”、“%2”的方式来引用“call”传递的参数信息。(后面会继续介绍)
cmd /S | /C | /K 字符串
其中字符串必须使用“""”引用,“/S”选项用于保留字符串的“""”并进行执行;“/C”或“/K”选项用于将“""”内部的字符串作为命令语句进行解释执行。需要注意的是“/S”选项不能与“/C”或“/K”选项一起使用,而且如果字符串语句是多条命令语句需要使用“&&”符号进行分割。
“path”是Windows中比较重要的一个东西,在MS-DOS系统中同样提供了“path”命令来定义当前批处理程序的资源路径信息。当需要在批处理程序中调用某一个文件是必须先进入该文件所在的目录,然后才能使用该资源;如果要引用另一个资源必须首选进入其所在的目录(当然你也可以使用完全绝对路径引用),显然这种模式比较笨拙,我们可以首选使用“path”命令指定当前批处理工作所需的所有目录,然后就可以在程序中直接引用资源名称了,既可以减少相应的代码量,也可以是程序更美观。“path”命令的用法如下:
path 目录完全路径[;...][;%PATH%]
path [;]
使用“path”命令可以可以查看当前批处理程序或MS-DOS解释器的执行目录路径;使用“path ;”命令可以将当前执行路径置为空;使用“path dirs”可以设置当前执行路径,其中“dirs”可以为一个目录,也可以为多个目录,多个目录需要使用“;”分割,同时还可以在原有的执行路径上进行路径扩展,可以使用内置环境变量“%path%”来引用原有目录。
“path”命令设置后,当程序中某个地方引用到某个资源名称,则会在“path”指定的工作目录中进行资源的查找,如果查找到了则引用,否则会导致错误。
exit [/B] [exitCode]
本篇主要介绍了批处理程序中的内置环境变量,流程控制语句等批处理中常见的命令,包括“IF”、“FOR”、“GOTO”等语句,当然还有其他的不怎么常用的语句和命令等待着大家自行去发掘。介绍的内容可能并不一定全面,希望能谅解。
前面介绍过批处理程序中的数据类型、操作符号、内置环境变量和常用的命令语句,这些都是学习批处理的基本知识,需要学习批处理这些知识必须了解到位。
学习某种语言的最终目的是能够读懂其他人编写的程序代码,用于解决自己的在日常生活或工作中的一些问题,然而前面介绍的基础知识就不能定能够满足这种目的了,所以下面来扩展一下其他常见的知识,总结一下之前介绍的知识,同时通过几个常用的案例来分析一下如何编写批处理脚本。
变量是批处理中的基础内容,常称之为“系统环境变量”。之前介绍了两种访问变量的方式“%变量名%”和“!变量名!”,其中前者是对普通变量的引用,后者是对延迟环境变量下的变量的引用,延迟环境变量大多用在复合式语句中,例如“for”、“if”等语句中。
之前在介绍“call”命令的时候,介绍过参数的取值方式——使用“%number”,其中number必须是数值,而且值大于等于0小于等于9。下面来看之前的例子:
将上面的代码保存批处理文件并执行,可以看到结果为:
%0=:deal
%1=test
%2=demo
请按任意键继续. . .
%1=
%2=
请按任意键继续. . .
首先来看看为什么为执行两次,“call”命令的执行流程不同于“goto”语句,当执行完对应的标签体后会再次回到当前“call”语句之后继续执行之后的程序,所以会执行两次。再来看看取值,“%%0”表示一个转义用于打印输出“%0”字样,当解释器执行到“call :deal %var% demo”语句时会跳转到“:deal”标签体并执行,可以通过“%0”等字样取到“call”命令语句后的参数,所以会打印出“:deal test demo”信息;然后再次进入“:deal”标签体,但是你会看到这次并没有取到参数值,为什么?因为这里是正常的批处理执行语句,并不是“call”语句的调用,但是可以看到“%0”取到的值为当前批处理脚本程序的完全路径名,这就是要提到的第二种参数化变量的扩展作用。
在批处理脚本中,默认情况下,可以使用“%0”来获取当前执行的批处理脚本程序本身,用于引用当前程序的完全路径名,这是MS-DOS解释器的扩展特点;而在特殊情况下,在取某些特殊命令语句的参数时,“%0”表示命令语句后的第一个参数值,而通常把这一个参数称为批处理标签本身,也就相当于把它视为批处理本身一样,“%1”、“%2”...“%9”等视为对正式参数的引用,所以从这个角度来理解,真正的参数索引应该是“1-9”。
在Windows系统中,我们可能看到将一个文件拖放到一个应用程序上,则可以使用当前应用程序打开当前文件的情况,那么在批处理中可不可以实现呢?答案是肯定的。来分析一下,该如何实现?如果要打开一个文件必须要指定该文件的路径地址才能打开,接下来的为题就是如何在批处理中获取拖放进来的文件地址。来看下面的例子:
这段代码中“inPath”变量用于获取用户输入的信息,可以输入,同样可以直接将目标目录或文件拖进当前解释器命令行,则可以立即获取当前文件或目录的地址。可以看成这是一种获取方式,但是这种拖放方式必须要在打开批处理执行解释器的情况下才可以使用。下面来看另一种方式,通过参数获取方式,先看例子:
将这段代码保存为批处理文件,然后将任意一个文件或目录拖放到当前批处理文件上,看看效果。惊讶的是可以看到,“%1”这个变量参数输入的信息就是我们想要的目标文件或目录的完全路径,而“%0”还是当前文件完全路径。上面介绍了“%0”表示的是当前执行程序本身完全路径,而这里的“%1”用于表示目标文件或目录的完全路径地址,这是变量参数的需要注意的另一个特点,“%1”在某些特殊的情况下才能发挥这种引用效果。
总结一下,在批处理脚本中的“%0”表示当前批处理程序本身的完全路径名,“%1”—“%9”表示对命令参数的引用,而这些参数应用最常见的就是“call”命令。需要注意的是“%1”在某些特殊情况下有另一种作用就是表示要执行的目标程序的完全路径,而这种用法大多是在拖拽文件的时候使用。
之前在“for”语句中提到了一种变量的扩展方式,非常类似上面提到的参数化变量扩展,然而在“for”语句中的变量名称只能为单个字母,所以可以与参数化变量区分开来。上面提到了“%0”参数可以表示当前程序的完全路径名,那么如何取到当前程序的工作目录呢?截取字符串,这是一个笨拙的方式,在批处理中提供了一种非常简单的处理方式——通过变量扩展来获取。
下面来看看批处理中定义的变量扩展方式,如下表:
来看下面的例子,在“%0”参数变量上进行扩展:
保存为批处理文件并执行既可以看到不同的效果。
其实,变量的扩展不仅用于“%0”参数,还可以应用到所有的变量上,包括“for”循环语句中的临时变量,但是大多数情况下用在“for”循环的临时变量上。经过测试这种单字符变量扩展的方式只能用于临时变量或参数变量的扩展上。
之前介绍过变量,在批处理中默认的变量都是字符串变量。如何实现在字符串变量值上追加字符串呢?如何实现字符串的拼接呢?下面就来讲讲这方面的例子,首先定义一个字符串变量,我们知道需要使用“%变量名%”的方式引用变量,如何将另一个变量的值追加到当前变量中呢?来看下面的例子:
从例子可以得出,批处理中的字符串拼接处理非常简单,不需要任何操作符号进行连接。为什么会这么处理?因为批处理中的变量引用方式实质是字符串的替换方案,之前也将过,当解释器执行到“%xxx%”字样的字符串时,会查找“xxx”所表示的变量值并替换当前语句中的所有的“%xxx%”字符串为指定的值,所以不需要任何符号干预;在开启延迟环境变量扩展功能的环境下,当解释器执行到“!xxx!”字样的字符串时,会查找“xxx”所表示的变量值并替换当前“!xxx!”字符串,并不会替换其他地方,这也是延迟环境变量和普通变量的一个最大区别。
字符串替换是比较常用的操作,批处理中的字符串替换需要依赖变量的扩展功能来实现,使用“:”进行字符串的替换操作扩展。用法如下:
%str:substr=value%
其中“str”表示字符串变量名称,“substr”表示字符串变量对应的值中的一个子字符串,“value”表示要将子字符串替换成的新的字符串值。意义就是将原字符串中的某一部分字符(串)替换为指定的内容。来看看下面的例子:
保存为批处理文件并执行可以看到效果,需要提到的是要替换的值是变量,则需要开启延迟环境变量扩展功能并使用“!xxx!”方式来引用该变量值,通过上面最后两条“echo”命令可以看成区别。
字符串截取也是比较常用的操作,批处理中的字符串截取同样需要依赖变量的扩展功能来实现,扩展用法与字符串替换有点类似,不过这个地方的扩展是基于数值进行字符串截取的。用法如下:
%var:~m[,n]%
其中“var”表示变量名称,“m”表示要截取字符串的开始位置索引数值,“n”表示要截取的字符的数量;字符串中的索引是从“0”开始的,也就是说字符串的第一个字符的索引为0,第二个字符索引为1,依次类推。如果只指定“m”的值则表示从第“m+1”个字符开始截取,直到字符串的末尾;如果同时指定“n”的值则表示从第“m+1”个字符开始截取“n”个字符。来看下面的例子:
保存为批处理文件并执行的结果如下:
原始字符串:abcdefgh
字符串索引:01234567
从第3个字符开始截取:cdefgh
截取前5个字符:abcde
截取3-6个字符:cdef
截取6-12个字符:gh
截取15-20个字符:
请按任意键继续. . .
从结果可以看出,上面描述的规则,“m”表示开始截取字符串的位置,“n”表示要截取字符串的长度;然而还可以看出,超过索引的截取是不会导致错误,但是我们还是需要尽量避免超出索引的截取操作。
上面介绍的例子都是按照顺序进行截取,而批处理变量截取不仅仅支持顺序截取,还支持倒序截取。倒序截取使用负数进行索引和位数的表示,表示从右边开始算起,顺序表示从左边开始算起。来看下面的例子:
将代码保存为批处理文件并执行的结果为:
原始字符串:abcdefgh
字符串索引:01234567
字符串倒数索引:87654321
倒数截取3个字符:fgh
从倒数第5个字符开始截取3个字符:def
从第2个字符开始截取到倒数第5个字符位置:c
请按任意键继续. . .
从结果可以得出看出,倒序截取的索引是从“-1”开始的,也就是右边的第一个字符位置为“-1”,第二个字符位置为“-2”,依次类推。
来总结一下字符串变量的截取规律,用法为“%var:~m,[n]%”,其中“m”表示开始截取字符串的位置索引数值,当“m”值为正数时表示顺序截取,从左边第一个字符(索引为“0”)开始算起,向右依次加一;当“m”值为负数时表示倒序截取,从右边第一个字符(索引为“-1”)开始算起,向左依次减一。“n”为正数时表示要截取的字符个数,表示从“m”位置算起,向右截取“n”个字符;当“n”为负数时表示从“m”位置算起,截取到从右边开始算起的“n”个字符的位置。使用以下的等式来说明:
① 在n无值的情况下,当m>=0时表示顺序截取,从左边第一个字符开始算起(索引为0)截取第“m+1”个字符(索引为m)后的所有字符;当m<0时表示倒序截取,从右边第一个字符算起(索引为-1)截取第“m”个字符(索引为-m)后的所有字符。
② 在n存在并且m>=0的情况下表示顺序截取,当n>=0时表示从左边第一个字符(索引为0)开始算起截取第“m+1”个字符(索引为m)后“n”个字符;当n<0时表示从左边第一个字符(索引为0)开始算起截取第“m+1”个字符(索引为m)与从右边第一个字符算起(索引为-1)算起第“n-1”个字符(索引为-n-1)之间的所有字符。
③ 在n存在并且m<0的情况下表示倒序截取,当n>=0时表示从右边第一个字符算起(索引为-1)的第“m”个字符(索引为-m)开始截取“n”个字符;当n<0时表示截取从右边第一个字符(索引为-1)算起的第“m”个字符(索引为-m)开始与从右边第一个字符算起(索引为-1)算起第“n-1”个字符(索引为-n-1)之间的所有字符。
也就说当“m”为正整数表示顺序截取,为负整数表示倒序截取,不论正负都表示截取的开始位置;当“n”为正整数表示截取字符的个数,为负整数则表示截取的终止位置。
“@”符号
关闭命令的回显,用法“@命令行”。
“>”符号
①输出重定向符号,用在命令语句后,将命令语句的响应信息输出到指定的空文件中(非空则先清空),用法“命令行 > 文件”。
②在“findstr /r”命令中表示匹配单词的右边界,需要配合转义字符“\”使用,用法“findstr /r "结束字符(串)\>" 文件”。
“>>”符号
①输出重定向符号,用在命令语句后,将命令语句的响应信息输出到指定的文件中(在原文件尾部追加),用法“命令行 >> 文件”。
②在“set /a”命令中表示逻辑右移位运算,将左边操作数的二进制码向右移动右边操作数个位数。即去除右边低位,左边高位补0(正数)或1(负数),用法“set /a num1>>num2”。
“<”符号
①输入重定向符号,用在命令语句后,将指定文件的内容作为命令语句的输入信息进行处理(一般为读取文件内容的一行信息),用法“命令行 < 文件”。
②在“findstr /r”命令中表示匹配单词的左边界,需要配合转义字符“\”使用,用法“findstr /r "\<开始字符(串)" 文件”。
“|”符号
①管道符号,用在多个命令语句之间,表示将前面命令语句的响应输出内容作为后面命令语句的输入内容进行处理,用法“命令行 | 命令行”,例如“help | more”。
②在“set /a”命令中表示按位或运算,对操作数的二进制码进行位比较,全为0则为0,否则为1,用法“set /a num1|num2”。
“^”符号
①转义字符,用在特殊字符前面,用于取消该特殊字符的作用。支持的特殊字符有“&”、“|”、“>”、“<”、“!”、“"”等,不包括“%”,用法“^特殊字符”。
②在“set /a”命令中表示按位异或运算,对操作数二进制码进行位比较,相同为0,相异为1,用法“set /a num1^num2”。
③在“findstr /r”命令的“[]”符号内字符串前表示不匹配“[]”内指定的字符集,用法“findstr /r [^字符(串)] 文件”。
④在“findstr”命令中表示一行的开始。
⑤在“echo”命令的输出语句中作为续行符号,可以将“^”后的下一行的字符串拼接在当前行后输出。
“$”符号
①在“prompt”命令中,称为选项转义字符,可以将其后的字符转义为特定的作用效果。
②在“findstr”命令中表示一行的结束。
“&”符号
①逻辑命令符,用在命令语句之间,表示多条命令语句进行连接视为一条语句执行,也就是说无条件的执行符号后的命令语句,用法“命令行 & 命令行”。
②在“set /a”命令中表示按位与运算,对操作数的二进制码进行位比较,全为1则为1,否则为0,用法“set /a num1&num2”。
“&&”符号
逻辑命令符,用在命令语句之间,表示只有当符号前命令执行成功时,才执行符号后的命令语句,用法“命令行 && 命令行”,与“||”符号相逆。
“||”符号
逻辑命令符,用在命令语句之间,表示只有当符号前命令执行失败时,才执行符号后的命令语句,用法“命令行 || 命令行”,与“&&”符号相逆。
“>&”/“<&”符号
输入重定向符号的变种,主要用于句柄操作上,其中“>&”表示将一个句柄的输出写入到另一个句柄的输入中;“<&”表示从一个句柄读取输入并将其写入到另一个句柄输出中。这两个符号比较特殊,基本不会用到。
“()”符号
①在“set /a”命令中表示算术括号优选运算。
②在“if”语句中表示语句块。
③在“for”语句中表示集合列表范围或语句块。
“!”符号
①在“set /a”命令中表示逻辑非运算,非0为1,非非0值为0,用法“set /a !num”。
②在开启延迟环境变量的模式下,用于引用延迟变量,即在“setlocal”命令后可以使用“!var!”来引用变量作为延迟环境变量处理,也就是说在“setlocal”命令后可以使用“!”来代替“%”,常用在“if”、“for”等复合语句中。
“~”符号
①在“set /a”命令中表示按位非运算,对操作数的二进制码进行位取反,1变为0,1变为0,用法“set /a ~num”。
②临时变量或参数变量增强型扩展符号,常用作对一个表示目录或文件的变量进行扩展操作,例如取得文件名称、文件属性等。大多数用在“for”语句中,对表示文件或目录的临时变量进行扩展引用,例如“%~i”表示去掉路径引号。
③字符串变量扩展符号,表示对字符串进行截取操作,用法“%var:~m,n%”。
“+”符号
①在“set /a”命令中表示算术加法运算,用法“set /a num1+num2”。
②在“copy”命令中用于连接需要操作的多个源文件,然后将内容合并在写入目标文件。
“-”符号
①在“set /a”命令中表示一个负数或者算术减法运算,用法“set /a -mun”或“set /a num1-num2”。
②在命令中可以表示选项前缀,替换“/”前缀;用在选项的“/”后表示取该选项操作的反向意义。
③范围标识符,在“findstr /r”命令中的表示指定字符范围内的任意字符,例如“[0-9]”表示数字。
“*”符号
①通配符,表示任意个任意字符。在很多文件和目录管理的命令中可以用于匹配任意文件或目录,例如:在“for /f”的“tokens”选项中表示所有字符。
②在“set /a”命令中表示算术乘法运算,用法“set /a num1*num2”。
③在“findstr /r”命令中表示将符号前一个字符(串)进行零次或多重匹配。
“/”符号
①在“set /a”命令中表示算术除法运算,求整除的商,用法“set /a num1/num2”。
②选项前缀,在命令后选项前修饰为命令选项,有时可以使用“-”进行替换。
“%”符号
①在“set /a”命令中表示模运算,求整除后的余数,用法“set /a num1%num2”。
②非延迟环境变量引用符号,在批处理中可以使用“%var%”的方式引用环境变量。
③在“for”语句中用于定义和引用临时变量,使用“%字母”的方式定义临时变量用于存储当前元素值。
④在可以传递参数的命令处理模块,用于引用命令传递的参数,使用“%num”(0<=num<=9)方式引用参数值,其中“%0”表示当前处理模块或批处理文件本身。
⑤单字符变量扩展引用符号,使用“%~单字符变量名”的方式来对该变量进行扩展引用,只能在“for”中的临时变量或参数变量上进行扩展。
⑥“%”特殊符号的转义字符,在批处理中使用“%%”表示实际的“%”,使用“%%%%”表示实际的“%%”。
“<<”符号
在“set /a”命令中表示左移位运算,对操作数的二进制码进行左移位操作,去除左边高位,右边低位补0。
“=”符号
①赋值运算符,在“set”命令中表示变量赋值操作。
②在“set /a”命令中表示算术运算。在算术运算中可以与其他算术运算符结合使用,表示选进行其他运算,然后在进行赋值操作,结合符号有“*=”、“/=”、“%=”、“+=”、“-=”、“&=”、“^=”、“|=”、“<<=”、“>>=”。
③在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo=”用于输出空行,“echo=off”用于输出特殊内容。
“,”符号
①在“set /a”语句中为多个表达式的分隔符。例如“set /a 1+2,3-2”等。
③在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo,”用于输出空行,“echo,off”用于输出特殊内容。
“.”符号
①批处理中使用“.”表示当前目录,例如“cd.”;使用“..”表示上一层目录(父级目录),例如“cd..”。
②表示文件名的一部分,作为文件名称和文件扩展每次的分隔符。
“ ”符号
空白符,表示命令和选项、参数,多个参数等之间的分隔符,某些情况下可以使用“,”替换
“?”符号
①通配符,表示单个任意字符。
②作为命令行语句的特殊选项,用法“命令 /?”,用于查看当前命令说明信息。
“""”符号
①当文件完全路径名中存在“ ”空白符是,可以使用“""”将路径名引起来作为一个完整路径名进行处理。
②在“for /f”命令中表示对扩展选项的引用,当在集合列表中使用“""”表示将当前元素作为字符串进行处理。
③在“findstr”或“find”命令中引用的字符串表示要搜索的字符串。
④强制作为字符串进行处理,在某些特殊情况下可以使用。
“''”符号
表示命令语句,在“for /f”中的选项集合中使用“''”引起来的语句将会作为命令语句执行并将结果作为“for”语句循环的内容。
“;”符号
①某些命令参数之间的分隔符,如果该参数可以包含多个值,可以使用“;”进行多个值的分割。
②在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo;”用于输出空行,“echo;off”用于输出特殊内容。
“[”符号
②在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo[”用于输出空行,“echo[off”用于输出特殊内容。
“]”符号
②在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo]”用于输出空行,“echo[off”用于输出特殊内容。
“\”符号
①表示根目录,例如“cd\”表示返回到当前根目录。
②目录和子目录、目录和文件的路径分隔符。
③在“findstr /r”命令中表示转义字符,例如“\<”和“\>”等。
④在“echo”命令后表示转义字符或输出空行,紧接“echo”命令。“echo\”用于输出空行,“echo\off”用于输出特殊内容。
“:”符号
②磁盘卷标符号,跟在“C”、“D”等卷标后表示盘符。
③在单字符变量或字符串变量中表示变量的扩展(替换或截取)操作,例如“%var:~m,n%”表示截取字符串,“%var:str=value%”表示字符串替换操作。
“::”符号
使用“::”开头的语句表示无效语句,相当于注释语句。
“nul”符号
表示一个空的字符(非空字符串),常见用于“pause > nul”。
可能会在某些情况下遇到这种情况“某一个文件夹被系统锁定无法删除”,尝试了各种方法都无果,是否很悲观。下面来看看如何使用批处理来解决这一问题。
首先来看看需要用到的DOS命令,在DOS中删除目录需要使用“md”命令,其中提供“/s”选项用于删除目录树结构,“/q”选项表示静默删除,但是使用“md”命令的限制是必须是空的目录,也就是目录中不能有文件,所有删除目录之前一定要先删除文件,删除文件需要使用“del”命令,其中提供了“/f”选项用于强制删除只读文件,“/a”选项表示删除任意属性的文件,“/q”选项表示静默删除。强制删除目录的代码如下:
可以将上述代码拷贝下来并保存为批处理文件(例如:删除目录.bat)然后按照用法使用即可。如果你有兴趣可以进行改写或扩展。
在网上看到一些例子,使用DOS命令来制作锁定文件夹,其实这种锁定文件夹是在文件夹的命名上做的文章。来看看如何实现,在DOS(CMD)命令行中进行操作:使用“md D:\test..\”命令在D盘新建一个“test.”的目录,我们指定在Windows中目录的命令不能以“.”开头或结尾,所以使用“DOS”命令可以打破这个常规,可以尝试一下在D盘中是无法使用Windows系统操作来操作该目录的;然后使用“start D:\test..\”打开目录;同时可以使用“del D:\test..\”来删除目录。要想知道这种情况的原理则需要了解Windows实际的工作原理,笔者暂时了解较少,无法解释。所以下面我把上面的内容进行整合一下,代码如下:
可以将上面代码拷贝下来并保存为批处理文件然后执行试试看。需要注意的时,上面的命令操作都是有一定条件限制的,请参考使用说明。
清理系统垃圾主要是指删除Windows系统内部自动生成的垃圾文件或目录,对Windows系统有所了解的人应该知道垃圾文件主要包括系统补丁的日志文件、系统自动生成的临时文件或目录以及用户使用过程中自动生成的临时文件、缓存文件等垃圾文件(最多的还属于IE的缓存文件),实际的清理就是删除这些文件,删除文件就要使用“del”或“rd”命令来实现。
在删除这些文件之前一定要知道文件的所在位置,系统的日志和临时文件大多在“WINDOWS”目录下,用户生成的垃圾文件大多都在“我的文档”等的指定文件夹中(可以自行查查哪些文件属于垃圾文件)。下面来看代码:
将上面的代码拷贝下来并保存为批处理(.bat)文件,然后执行即可。如有需要,则可以自行添加其他需要清楚的目录和文件,使用的命令主要有“del”和“rd”;如果需要清除并移到“回收站”中,可以使用“move”命令来实现。
系统组件是系统本身不可缺少的一部分,很多软件缺少了这些组件都无法正常运行。在Windows系统中最基层的系统组件分为DLL和OCX两种,其中DLL(全称Dynamic Link Library,“动态链接库”)文件,它是很多系统软件都依赖的一种对立程序;OCX(全称Object Linking and Embedding (OLE) Control Extension,“嵌入式对象控件”)文件是一种共享式的对立程序。首先了解了这两种组件,那么重新注册则就是将这些DLL或OCX组件卸载后重新安装一遍。那么使用什么命令来执行完成了?
在Windows系统中提供了一个“regsvr32”外部程序来进行DLL和OCX文件的注册和卸载操作,虽然是一个外部程序,但是同样提供了命令操作行,可以通过在运行窗口或命令行中输入“regsvr32”命令来查看“regsvr32”工具的使用方法,这里不多说,具体选项应用都有说明。需要注意的是“regsvr32”命令只能用于操作“.dll”或“.ocx”文件。下面我们来看重新注册系统组件的代码(这里使用“for”语句来实现):
当系统出现不稳定的情况下,可以使用这种方式修复一下系统。
批量文件重命名,这个问题在之前已经说过,但是没有讲过如何实现。下面我们就来看看这个案例。
或许你在某些网站上下载一系列文件时,这些文件的名称都包含了该网站预定义的部分名称前缀或后缀,是否感觉不雅观,如何去掉这些前缀或后缀呢?一个一个修改?太OUT了!使用批量修改软件?我的第一想法就是别人可以做的批量修改软件我为什么不能。上面已经学习了批处理,那么我们就使用批处理实现简单的批量修改文件名称。
要修改文件名称,必须要使用“ren”命令,具体操作就是使用“for”循环取到每一个文件名称,然后在名称上进行修改,最后使用新的字符串名称来替换原有的字符串名称即可。代码如下:
上面的批量文件改名只是一个简单的示例,更复杂的改名方案等待你去实现。
进程是Windows系统中的一个重要概念,一般对应一个正在执行的程序,在MS-DOS同样提供了对进程实现管理的命令工具,常用的有“tasklist”命令和“taskkill”命令,其中“tasklist”命令用于查看进程信息,可以根据一个进程名称或进程ID来查看进程的相应信息;“taskkill”命令可以用于终止进程,可以根据一个进程名称或进程ID来终止进程或所在进程树。
端口是Windows系统中的另一个重要概念,具有远程通信功能的程序一般至少需要监听一个端口来实现通信,端口不可以重复使用,一般一个端口只对应一个进程,但是一个进程可以对应多个端口(具体的关于“网络端口“的详细描述可以参考一些其他资料)。在MS-DOS系统中提供了“netstat”工具来查看网络端口,同时还可以查看端口对应的进程信息。下面我们就来实现这个例子:
可以将上面的例子保存为批处理文件执行即可,提供了网络端口的查看工具、根据端口查找进程的工具以及进程终止工具等,同时提供了一个关于字符串长度获取和空格填充的方法,当然你还可以自行进行扩展。
服务也是Windows系统的一个重要概念,一般服务是其他程序运行的基础环境,关于服务的具体信息可以自行参考其他资料。在MS-DOS提供了一个强悍的工具“net”命令,用于对WIndows基础信息进程综合管理,当然它也可以管理服务。“net”命令如何进行服务的启动和关闭管理呢?来看下面的例子:
上面的代码中,用到了“net start ...”和“net stop ...”命令,其中“net start”命令用于查看所有已启动的服务列表,“net start ...”命令用于启动指定服务名称的服务,“net stop ...”命令用于关闭指定服务名称的服务。
MS-DOS批处理脚本支持的数值类型只能是整数类型,如果是小数则将作为字符串进行处理,也就是说默认情况下批处理只支持整数运算,本案例就来介绍一下如何让批处理支持小数运算,案例以小数加法为例进行讲解。
其实实现过程是一个算法理论,由于批处理支持整数运算,所以需要将小数的整数部分和小数部分分开进行运算。这个地方的运算原理是:分别提取整数部分和小数部分;以原小数中较大的小数的位数为标准进行补0操作,整数部分在右边低位补0,小数部分在左边高位补0;然后去掉小数点,从右边第一个开始依次向左推移并计算其和,大于9则想左边相邻位进1并保留结果个位值,计算完成后还原小数点位置即可。例如:要计算 4567.5+5.6789,则处理后的数字为45675000+00056789,然后按位做加法操作,这个方法只是模拟实现,当然会存在一定的限制。代码如下:
曾经在网络上看到一个帖子,楼主写了一个批处理,可以生成一个“I LOVE YOU”图标文件,感觉很是NB。但是这需要借助Windows的第三方脚本工具进行制作。具体的这里不研究,这个批处理附件中也有,可以参考一下代码。这里介绍一个发送给指定电脑一个特殊的文字信息,代码如下:
关于上面的代码,其中“ping -n num 127.1 > nul”这一句表示的是使用“ping”命令来实现延迟操作,这种方式使用的比较广泛。其实上面这个短小的例子的信息都是通过特殊字符进行拼凑的,如果你有艺术细胞,同样可以作出这样的效果。
废话、闲话也说了这么多,到这里我对批处理基本东西的整理也就到此结束了,知道了这些信息在去读别人写的批处理脚本应该也不是一件特别费力的事儿了。通过这些介绍,唯一的感受就是批处理程序也一样的强大,其实很多其他的编程语言都提供了对批处理支持接口,可以自行查一下你当前所会的语言的对应接口,调用试试即可。
关于批处理的学习对应我来说应该是一个过渡性学习,以后不一定会用到,但是很多常用的还是应该记住,现在很多大型的服务器都提供有批处理脚本支持,所以读的懂它还是有一定必要的。别的不多说了,废话就到处结束。