[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[其他] 批处理之我见

本帖最后由 leeonix 于 2011-10-19 20:42 编辑

By LeeoNix 2011年10月19日

2011年10月8日,C语言的作者。Dennis Ritchie去世了。看着这个消息我发呆了很久。可以说,你看我这篇文章的时候,面前所有的“虚拟”的东西,都与这位大师有关。他是真正的大师,那天我决定写1000行C或者其他的代码。那天我写了大概500行的C代码,写了一个生成批处理的Python脚本。纪念这位大师,作为一个程序员,除了写更精细的代码,没有别方式去纪念他。

和朋友聊天,他说,既然你用到了Python,就全用就是了。干吗还要生成批处理呢?我的回答,批处理的环境变量依赖是很方便的,而且我还要用vc编译3个vc工程,一个Delphi工程。还要用sed处理合适的文本输出。用Python组合这些操作就非常麻烦了。

写完这些之后,我就想写一篇文章,以前,一个后辈说从这里学了不少东西,今天我就注册个号发一篇文章回馈一下。其目的是,批处理该用什么,以及什么时候该用到批处理。

1、批处理的定位。

所谓的Windows批处理。实际上是CLI(command-line interface,命令行界面)的一种,具体见(http://baike.baidu.com/view/160512.htm)。而CLI区别与用户图形界面,其优势是,可以根据各种命令组装成批量执行的命令。
批处理其优势就是Windows提供的原生工具。这一点优势就足够说明为什么在Windows下使用批处理,多的优势根本不用多说。其欠缺的也很明显,缺乏模块化的语句,缺乏对数字和逻辑类型操作的方法,条件分支和循环语句都很弱小,字符串操作也很弱。

批处理依赖的环境是一个开放式的大环境,面向整个系统。换句话说是其实是“不安全”的,比如我用call默认调用另外一个批处理,实际上你可以在主题批处理上用到被call的批处理里面的变量名。打个不恰当的比方说,就像一个大厂房,倘若你和你的异性伴侣在OOXX,实际上路过想看的人都是可以看得到的。虽然是可以用setlocal...但其优势又是因为是开放式的,而且可以根据环境变量去获取,各种东西随便用,在轻量级调用方面,就省却了很多麻烦。

如果有工厂经验的人,会理解我说的话。其实批处理最好的定位,就是一个大的方便的组装车间。而不要特别去想成为加工车间。强求只会陷入误区。

2、关键的操作符。
Unix最初的创建者中,有位大师叫Doug MclIroy。他低调的隐藏在Ken Thompson和Dennis Ritchie之下。并不为所有程序员所知。他为Unix发明了管道以及使用管道操作符"|",而这点被借鉴到了Windows系统。

看到这里,请记住管道以及管道的发明者,Doug MclIroy。

管道的意义非常简单:上一个指令的输出作为下一个指令的输入。搜索管道的介绍,你会看到管道的基本指令。ls -l | more。而在Windows下,其实这个也是很有意义的指令。比如C:\Windows\System32这个文件夹下,有非常非常多的文件。一次是看不完的,那就输入C:\WINDOWS\system32>dir | more。dir显示不全的交给more显示就可以了。

举个我实际的例子,我写的Lua脚本,有个debug库,我为了提高效率,在给别人的时候会把这个有关debug的信息处理掉。只要利用sed把根据关键字注释掉,然后扔给lua编译器便以为byte code就可了。listfile是我预先写好的或者用>操作符生成的临时文件。
代码:
for /f %%i in (%listfile%) do (
    sed.exe "s/debugstr\./--/g" %%i | luac.exe -o %TEMP%\script\%%i -s -
)

有关管道的介绍,可以从网上找到很多。

输入操作符,输出操作符。< > << >>这也是借鉴的Unix系统的操作符。只能用于标准输入输出进行操作。而例如stderr输出的,则不会被使用。具体在下面会有例子。

3、命令行工具。
使用批处理,就与命令行工具息息相关。而cmd.exe本身提供的指令非常有限,参数也很有限。所以命令行工具是主要补充。其实Windows本身提供的命令行工具,打开C:\WINDOWS\system32,会看到很多普通图标的工具,也可以从网上查到大概的功能。但很多提供的功能很有限用起来也比较无奈,比如findstr,还不如下载一个grep用。而自己用编译类语言写的工具,或者用脚本语言写的,只要符合标准输入输出流的,都可以作为工具集使用。

Unix工具的易用性是毋庸置疑的,在Windows上使用,好几个实现版本。

gow这个是比较全也比较轻量的,是整理的gnu工程再发布的。
http://wiki.github.com/bmatzelle/gow/
gnuwin32是gnu官方提供的,文档比较全。更新比较方便,但很多可能你不需要的东西在里面。
http://gnuwin32.sourceforge.net/
UnxUtils也是一个整理的工具集。
http://sourceforge.net/projects/unxutils/

个人推荐gow。

使用unix工具集,会有几个选择。面临很多的选择,dir还是ls?findstr还是grep?del还是rm?copy还是cp?就速度上,Windows提供的当然快很多,但作为使用管道的工具来说,还是后面的工具更合适。

但是很多冲突需要注意,举个例子:find命令,被windows定位为搜索字符串,但在Unix工具里面是搜索文件的,而find命令搜索文件,是很方便的,结合xargs可以作很多事情。类似的冲突还是比较多的。而gnu提供的find命令是很好用的。扔掉windows带的那个find.exe,从C:\Windows\System32下可以安心删除它。换成grep。

4、正则表达式。
文字处理方面,正则表达式是必须的,但在批处理上用大多数的正则表达式是无意义的。
Unix最初的创建者中,还有有位大师叫Brain Kernighan。他在《程序设计实践》里介绍了一个极简单的grep实现代码。只提供了四个操作符"." "*" "^" "$",这四个字符,体现了一个好的“记法”可以增长人的工作效率。在书里面提到了,就这四个操作符就可随意解决大部分问题。而另一本书《代码之美》的第一篇也是对这个实现的一个介绍。《程序设计实践》里,大师说了:好的记法只有与人们的工程经验相结合,才能产生自然而有效的工具。

而为什么要使用这些字符?接触批处理的,都会有一个概念,叫“通配符”。比如dir *.dll这样的。*代表了“所有”。而*号,就是dir这个工具提供的“记法”,让用户明白“所有”这个概念。仅仅使用dir这样的工具提供的是远远不够的。所以才要使用正则表达式。在批处理里面使用简单的正则表达式足够,如上面提到的4个。而利用grep这样的工具过滤,会更容易让人理解。而上面的dir *.dll也可以用dir | grep "\.dll$"来做到同样的功能,但过滤了很多无用的信息方便下一步操作。

进一步的例子:dir | grep "\.dll$" | awk "{ print $1, $3 }" 会输出列表内dll文件的日期和大小。
利用正则表达式可以让你找到你想要的。

5、纯文本。

Eric Raymond,在《Unix编程艺术》里,多次提到了纯文本的威力。缺乏数据结构支持的批处理利用 < > << >> 输出流生成中间文件,再经过处理之后,就成为下一个需要用的参数。也可以生成一些配置文件,作为其他工具使用的参数来处理。如果批处理的功能遇到问题,也可以通过模板,利用输入输出流生成一个临时批处理来操作。不要太信任二进制文件,但一定完全信任纯文本。
比如获取文件名,用dir /b > list.txt生成一个list文件,然后用for /f %%i in (list.txt) do echo copy /y %%i %TEMP%\%%i.bak类似这样的循环操作,操作完del list.txt,这就成为一个备份文件的好例子。

dir /b > list.txt
for /f %%i in (list.txt) do echo copy /y %%i %TEMP%\%%i.bak
del list.txt

再举个例子,我写了个工具,是一个命令行打包的工具。但支持的参数类似这样的格式:
#-------------------
#(路径) (类型)
%TEMP%\script script
D:\Work\images bmp

然后打包成一个我需要的文件。我通过使用%cd%获取当前目录,然后获取合适的路径再调用我自己写的打包工具。
echo %TEMP%\script script > pack.txt
echo %cd%\images bmp >> pack.txt
packer pack.txt
del pack.txt
这样一个简单的批处理,就让我的工具做到与环境无关的通用性了。而且参数可以通过生成这个配置文件可编辑。

6、脚本语言。

现在脚本语言越来越多了。awk,perl,python,lua,ruby,javascript,甚至java和C#都可以参与进来。
为什么要用到脚本语言。就是为了作为批处理功能的补充。我在第一条说过,批处理的定位是组装车间,不是加工车间,而加工车间,交给脚本语言。
学一种甚至几种脚本语言是非常有必要的。
虽然上面我用了awk,但awk并不完全推荐,局部简单的还可以,其功能完全可以被perl替代。awk的速度优势,在现在的计算机速度下,已经可以忽略。
而我常用的单行命令基本可以用perl替代,而非单行的脚本可以用python也可以用lua来写。
为什么要用到脚本语言:
    a.批处理对于字符串的处理是很弱的。缺乏更好的替换,缺乏类似printf这样的格式化输出,更缺乏整个Template替换。但写一个简单的perl脚本或者python脚本就完全弥补。
    b.批处理缺乏数值计算的能力。有的地方日期和数值比对是很重要的。
    c.批处理缺乏合理的数据结构,数组,key-value的表格。而针对字符串生成数据结构的split和join的字符串处理。

顺便说一下个人的喜好问题,我是强烈的反感带“VB"两个字母的东东的,比如VBScript我是绝对不用的。

最后,没什么可说的了。
提醒一下,关于字符串以及文本的处理,可以说,你能想到的,20多年前美国玩操作系统的那些老家伙都想到了,你没想到的,那些老家伙也想到了。利用管道很多都可以做到。
引用荀子的一句话:吾尝终日而思矣,不如须臾之所学也。
2

评分人数

    • vsbat: 难得有前辈出来技术 + 1
    • cjiabing: 专业,中肯,敬佩~技术 + 10

2011年11月8日,C语言的作者。Dennis Ritchie去世了。看着这个消息我发呆了很久。
看着这个消息我也发呆了很久。

TOP

本帖最后由 CrLf 于 2011-10-19 20:15 编辑

20 年前的批处理绝不会比现在挖掘得更充分,强如微软也不可能把还没出现的 cmd 吃透,不说别的,三四年前的经典代码合辑中的许多内容放在现在已经算中低水平了(不过我感觉主要是因为那个合辑本身不够经典…)。
楼主说得确实有道理,批处理是加工车间也好,组装车间也罢,实用至上,适时就行了…倒无需非苛求全面发展

TOP

尺有所短,寸有所长,各尽其能,综合应用,先解决问题,再考虑其他。。

TOP

2011年11月8日,亲,穿越了

前些日子给实习生讲课还提到了肯.汤普森和丹尼斯.里奇,谁知道没过几天大师就登船了。各种蹉跎啊~~~
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

2011年11月8日,亲,穿越了

前些日子给实习生讲课还提到了肯.汤普森和丹尼斯.里奇,谁知道没过几天大师就 ...
Batcher 发表于 2011-10-19 20:29



    失误,没仔细看。哈。

TOP

回复 5# Batcher


    Batcher版主是老师吗?哈哈

TOP

20 年前的批处理绝不会比现在挖掘得更充分,强如微软也不可能把还没出现的 cmd 吃透,不说别的,三四年前的 ...
CrLf 发表于 2011-10-19 19:30



    20年前,换句话说,非windows时代。设计和使用Unix和类Unix的那些老家伙们玩的,比最初的dos强了不知道多少。windows就没在CLI定位太多,但Windows的CLI方式都是从Unix系统借过来的。我建议去看看《程序设计实践》这本书。Brain Kernighan和Rob Pike的经验是足够让人借鉴的。

TOP

可以说,遵循Unix哲学,如果能用工具根据配置生成一个批处理去用,就别用手写。这是我坚信的一条。

TOP

真失忘啊,LZ为什么对VBS这么反感呢!真难为我费了那么大的劲学了,虽然说“简单”了些,但是做为一个外行入门也许是个不错的选择(就像我这样的),其实个人倒是满喜欢C的,语法很严谨。其它的也就是JAVASCRIPT了。
以上是费话练习,最要的就一个字——“顶”
枫中残雪:风停了,我的心却在动,让我心中的寒意走向远方

TOP

rar、7z、tar神马的不是挺好挺强大么,你写的命令行打包的工具也是作业性质的吗?
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

我写的打包是给游戏用的,游戏专用的虚拟文件系统。并不是压缩包。。。

TOP

本帖最后由 leeonix 于 2011-10-19 21:47 编辑

概括总结,图片处理,是一个从32位色点阵图,转化为d3d纹理文件,打包进虚拟文件系统的工具。脚本是把文本文件,编译为byte code,然后打包进虚拟文件系统。其他的文件也类似,比如声音文件。其实这个工具也只是调用了游戏用的打包解包库的一组简单的Lua脚本。复制好,最红用zip -9 -r打包为zip文件发送。

TOP

LZ为什么反感VB,难道不好吗,VBS和VB6可能老了比较落后了,但是还是能开发出很好的软件,况且现在还有VB.net,还有PB等。另一个方面,VB6和VC6用的是同一个编译器和连接器,.net系列代码可以直接互转,似乎没什么理由反感VB
第三方命令行工具编程
Http://Hi.Baidu.Com/Console_App

TOP

类Basic语言包括VB并没有任何好的帮助。而且这些语言是有害于思考的,编程人员学习语言,其实是学习符号系统,可以说,如果一种语言没有任何值得学习的地方,就不要学。

TOP

返回列表