Windows 批处理脚本学习教程

Collected by Clove

第五章:组合命令 管道命令

5.1 组合命令

组合命令 & 、&& 和 || 是一类用于两个或多个命令语句之间起衔接作用的符号。这对于我们想一次性执行两条或多条命令,以及前面命令执行结果的成功与否作为后面命令是否被执行的衡量标准,起着决定性的作用。

5.1.1 &

通过紧随的例子,echo Checking what executable files we have in WINDOWS... & dir C:\WINDOWS\*.exe & echo And we got lots of stuff here. 我们不难理解 & 在多个命令之间所起的连接作用。事实上,我们完全可以将这三者分成3行来独立执行,因为它们之间是相互独立的关系。不论三者中每一条命令的结果如何,后面的一条命令总能被得到执行(这是与下文 && 和 || 的不同之处)。

5.1.2 &&

&& 作为组合命令之一,与 & 类似,也有着并列多条命令并将其按顺序执行的功能。与 & 的不同之处,也许此时您已经猜到了,没错,如果多命令中的某一条命令执行出错时,后面的所有命令将不会再被执行;如果一直没有出错则会一直执行完所有的并列命令。为了很好的对比它们之间的区别,我们分别尝试一下下面的两个例子。
echo Checking if we have the following directory... & dir "E:\starcraft II" & echo Seems it does not exist.
echo Checking if we have the following directory... && dir "E:\starcraft II" && echo Seems it does not exist.
它们的区别是一目了然的,前者会有 Seems its not exist. 的输出,而后者却没有。

5.1.3 ||

|| 的用途与 && 的功能恰好相反。当遇到执行正确的命令后将不再执行后面的命令,如果没有出现正确的命令则一直执行完所有命令。例如 dir D:\test || md D:\test ,如果 D:\test 存在,即第一条命令执行正确的话,后面的创建 D:\test 就不会再执行了;相反,如果第一条命令执行出错,那么后面的命令就起作用了。

在混合使用的时候需要注意它们的优先级。分析下面几个例子有助于我们理解它们的执行效果(如果我们的机器上并没有 Z: 盘的话)。注:浅蓝色的命令表示会被执行到,而深蓝色的命令将不会被执行到。
dir Z: & dir C: || echo Howdy
dir C: & dir Z: || echo Howdy
dir Z: && dir C: || echo Howdy
dir C: && dir Z: || echo Howdy
dir C: && dir C: || echo Howdy

dir C: || echo Howdy & echo Hi there
dir C: || echo Howdy && echo Hi there
dir Z: || echo Howdy & echo Hi there
dir Z: || echo Howdy && echo Hi there
实验一下,看看结果是不是跟预期的一样。

5.2 管道命令

5.2.1 > 、>>

它们是输出重定向命令,在第2.2节中已有详细的介绍。其主要功能就是将一条命令或某个程序输出结果的重定向到特定文件中。> 与 >> 的区别在于,> 会清除调原有文件中的内容后写入指定文件,而 >> 只会追加内容到指定文件中,而不会改动其中的内容。下面将会是一个很有用的例子。

众所周知,System32 文件夹是多数木马潜伏和发作的好地方。当我们刚装好机器的时候,可以给此时机器里还没有病毒、木马的 System32 文件夹里的所有可执行文件(.exe)和动态链接库文件(.dll)作个记录。等以后发觉 System32 里多了可疑的东西的时候再作个记录,然后跟之前的记录对比一下,就很容易发现问题了。
为了方便作记录,我们可以执行类似下面的一条命令:dir %windir%\system32\*.exe>D:\%DATE:~0,10%的exe文件.txt 。其中,%windir% 是当前启动系统所在的目录,默认情况下通常是 C:\WINDOWS ;%DATE:~0,10% 是指当天的日期,比如2007-11-30,如果您没有忘记在3.1.4节里曾描述过的话。而整条命令的结果就是把 System32 里的所有可执行文件名称及信息记录到一个指定的文本文件里了。同理:我们可以记录 System32 里的所有 dll 文件:dir %windir%\system32\*.dll>D:\%DATE:~0,10%的dll文件.txt 。
在经过一段时间后,我们可以再次使用上面两条命令,从而得到两个新的记录文件。然后对比一下两个文件看看有什么差异。DOS 命令里提供了这样一条命令 fc ,它允许我们对两个文件之间的差异进行比较。使用时就像:fc d:\2007-11-30的exe文件.txt d:\2007-12-01的exe文件.txt 。[1]

5.2.2 |

没错,只是一条竖线而已。它可以将它左边命令的输出结果放到它右边的命令里作为输入参数。这种用法据说在 Unix 里很常见。

有个能简单检测机器是否中冰河木马的例子:netstat /a /n | find "7626" && echo 已被冰河感染 || echo 未被冰河感染 。其中:
netstat 用于显示当前的网络连接情况,参数 /a 显示所有连接和监听端口;/n 以数字形式显示地址和端口号。仅仅执行 netstat /a /n 后,您将会看到输出的结果为:各种协议下的本地和目标的地址及端口,以及它们的连接状态。
命令 find 则可以搜索指定的字符串,在指定的文件中。netstat /a /n 的输出结果将通过 | 成为命令 find 的第二个参数。因此整个的一条命令可以理解为:在网络连接状态的输出结果中,查找字符串 7626 ,如果查找成功的话,将输出被感染的提示,否则便提示未感染。&& 和 || 请参考第5.1.3节的例子。(端口 7626 是冰河所使用的默认端口。事实上,这并不是一个严谨的检测冰河木马存在的方法,但它却是说明组合命令和管道命令一个很好的例子)

5.2.3 管道命令还有 < 、<& 和 >& ,它们并不常见,在此暂时不讨论了。

Collected by Clove--Mail to Me

Windows 批处理脚本学习教程