![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-09-15 05:25 |
共 47,812 主题排行 / 349,917 发帖 / 今日 0 篇 / 48,268 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » [讨论]批处理编程的异类 |
| 可打印版本 36,680 / 26 |
| 第1楼 willsort | 发表于 2004-06-20 00:00 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
[讨论]批处理编程的异类 批处理编程的异类 本主题的目的是针对批处理编程的异类(http://www.cn-dos.net/forum/viewthread.php?tid=8905)中所涉及到的各类技术问题进行讨论和答疑。 本人欢迎大家就以下话题提出自己的意见和建议。 1,对此主题中涉及到的技术和技巧的质疑; 2,对此主题中涉及到的技术和技巧的改进; 3,此主题未涉及,但是在批处理编程领域很有挑战性的主题; 同时,为了保证版面的整洁和秩序,也因为本人时间和兴趣的限制,对于以下的各类话题,请各位避免提出,本人无法保证对此给予任何答复。 1,仅仅称赞或者毫无内容的话题; 2,与批处理编程主题毫无关联的话题; 3,要求提供批处理编程资料的话题; 4,要求提供每句详解的话题; 希望它能对各位(包括我本人)对批处理编程的认识加深和水平提高有所帮助,也希望大家能对它的秩序维护做出自己的努力。 [ Last edited by willsort on 2005-10-13 at 13:03 ] |
|
| 第2楼 willsort | 发表于 2005-01-17 00:00 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
FDISK的命令行参数 FDISK的命令行参数 FDISK仍然是大家很常用的分区工具,他支持命令行操作也不再是是一个“未公开的秘密”,早在99年就有人发现了FDISK的一些特殊参数,并将这些应用到了批处理文件中,自动分区似乎并不太遥远。然而,仍然有很多的问题需要解决,硬盘大小的确定仍然无法单独依靠fdisk来实现。 虽然有了gdisk等第三方工具,但是能用DOS自身命令完成相应功能,仍然有很大的应用前景。 下面是我翻译的国外的关于FDISK命令行参数的资料,国内也有类似的文档,但是似乎都不如下面的文档全面。 (CREDIT: 这份文件的拷贝来自 Michael Jacobsen at http://www.jacobsen.sdn.dk/fdisk) |
|
| 第3楼 英雄不色 | 发表于 2005-01-22 00:00 |
| 中级用户 发帖 33 积分 221 | |
|
willsort,您好.请问在批处理中如何实现段注释呢?我的思路是这样的.doskey /*=goto %explain%doskey */=:%explain%问题是如何才能将变量%explain%有序增值.站长在批处理一文中提到了"COUNT是变量的计算工具,如原来C的值为1,执行COUNT C后C的值就为2。BE是个强大的批处理增强工具,在Norton Utilties 8.0中带有。KPUSH是键盘缓冲工具。"这个COUNT命令请问您有吗?还有一个问题.我想在批处理中也会常用到.那就是如何把键盘输入加载到变量.有没有像input这样的命令.比如:
@echo offecho 请输入您的名字:input %1在运行到input后就会提示用户输入.待用户输入后将用户输入的保存到变量中,以便调用.期待您的答复!先说声谢谢了. |
|
| 第4楼 willsort | 发表于 2005-03-18 00:00 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
Re 英雄不色:
很抱歉,因为鲜有关注此帖的朋友,所以我也丧失了对他的关注的热情。不过见到你的问题,很是高兴。 下面是在兄所发的新主题中所作回复,全文引用:
另外,批处理的段注释有一种比较常用的方法: 另外,还有其他各种注释形式,比如: 1、:: 注释内容(第一个冒号后也可以跟任何一个非字母数字的字符) 2、rem 注释内容(不能出现重定向符号和管道符号) 3、echo 注释内容(不能出现重定向符号和管道符号)〉nul 4、if not exist nul 注释内容(不能出现重定向符号和管道符号) 5、:注释内容(注释文本不能与已有标签重名) 6、%注释内容%(可以用作行间注释,不能出现重定向符号和管道符号) 7、goto 标签 注释内容(可以用作说明goto的条件和执行内容) 8、:标签 注释内容(可以用作标签下方段的执行内容) 诸如此类,不一而足。 ------------------------------------------------ 2005.07.18 最近的发现表明,在Win9x和MSDOS平台下,可以在批处理中可以通过特殊的方法调用DOSKey的宏命令,但是它仍然对段注释的主题无法起到明显的助益作用。示例如下: [ Last edited by willsort on 2005-7-18 at 14:18 ] |
|
| 第5楼 willsort | 发表于 2005-09-26 23:02 |
| 元老会员 发帖 1,512 积分 4,432 | |
if语句中防空字符的选择
以上内容转自 {16327}批处理疑难征解:防空字符的选择 http://www.cn-dos.net/forum/viewthread.php?tid=16327 |
|
| 第6楼 willsort | 发表于 2005-09-26 23:05 |
| 元老会员 发帖 1,512 积分 4,432 | |
引用环境变量中路径时的防御字符的选择
以上内容转自 {16327}批处理疑难征解:防空字符的选择 http://www.cn-dos.net/forum/viewthread.php?tid=16327 |
|
| 第7楼 willsort | 发表于 2005-09-26 23:29 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
目录的存在判定 这似乎是个很简单的问题,在我见过的和我编过的绝大部分批处理中,目录判定都使用的是这个经典格式:
if exist directory\nul command argument(s) 可以说,这个技巧的创始者确实对DOS的研究十分深刻,至少他发现了 nul 所代表的设备管理机制与文件管理机制之间复杂而微妙的关系,nul设备与. 和 .. 等一样可以在大部分路径下直接引用而不会产生系统错误。 但是,也正像 .. 不能在根目录下引用(这在NT CMD中被修改了)一样,nul也有它的局限性。 当我们在 MSDOS7.10 的环境中加载了 DOSLFN 以实现长文件名支持时, DOSLFN 的某些 BUG 会将 \NUL 的引用转义,此时会将文件判定为目录。
如果说这仅仅是doslfn的问题,那么我们可以禁止DOSLFN,然后再将测试阵地转到光盘上。由于光盘具有独特的文件系统CDFS,\NUL的引用失效了,目录仍然无法被识别出来,不过总算不会把文件误判作目录了。
我们再转到时新的CMD@WinXP中,如果目录名中包含空格,则无法用长文件名识别其存在。
[ Last edited by willsort on 2005-10-26 at 11:16 ] |
|
| 第8楼 无奈何 | 发表于 2005-09-27 00:41 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
关于目录的存在判定
用 if exist directory\nul command argument(s) 的方法只要目录含有空格无论如何是匹配不正确的。 我实际应用中一般用下面的方法: 这样会很准确,但也是有缺点的,那就是会进入其目录。 |
|
| 第9楼 willsort | 发表于 2005-09-27 17:10 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
Re 无奈何:
上文因为时间关系,并未完成就贴出了,所以遗漏了很多问题。 对于含空格目录名,可以使用8.3短名判断,或者也可以使用以下的方法: if exist "my test\*" echo Exist directory "my test" 当然,与你的方法一样,这只使用于NT系列的命令行,兼容性上很不够好。 在DOS下,我正在考虑dir+find的方案,不太成熟,如下: dir directory /ad | find ".." i>nul if not errorlevel 1 echo Exist directory "directory" 但是它也有缺点,比如无法正确判定类似 “e:\” 这样的目录。 而关于你的md+cd的方案,进入目录倒不太要紧,可以cd..退出,但是它无法判断跨分区路径,需要改用 cd /d ,返回路径时却更麻烦,另外还需要禁止 C命令可能出现的错误消息。 pushd "e:\test_path" 2>nul && echo Exist directory "e:\test_path" && popd 但是,只能在NT下使用的方案,局限性还是太大了。 [ Last edited by willsort on 2005-9-27 at 17:55 ] |
|
| 第10楼 willsort | 发表于 2005-10-13 11:29 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
文件名中的扩展名的判定 文件名中的扩展名的判定 此帖缘起于 英雄不色 兄在 {1515:8762} 的第7个问题。
1、如果文件名所指的文件是单个文件,且存在这个文件,且其中不包含路径的指定,那么可以使用以下的方案; 2、如果文件名所指的文件是单个文件,但是它不存在,且其中不包含路径的指定,那么可以使用以下的方案; 3、如果程序应用环境是NT系列的命令行,且文件名中只有一个分隔主文件名和扩展名的句点,可以使用以下的方案; 4、使用Strings、aset等可以获取文件扩展名的第三方工具,不过它们对长文件名和中文文件名的支持可能不很完美。 [ Last edited by willsort on 2005-10-13 at 13:01 ] |
|
| 第11楼 不得不爱 | 发表于 2005-10-13 13:21 |
| 超级版主 发帖 2,044 积分 5,310 来自 四川南充 | |
|
有SPFDISK的批处理参数吗?
|
|
| 第12楼 无奈何 | 发表于 2005-12-02 22:41 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
to willsort
关于 PING 命令的一些问题,几经搜索也一无所获,只能截取 ping 命令执行前后 %time% 变量计算差值,实际测试看看规律。相信兄早已做过这样的测试,不具体贴数据了。总结如下: ping -n x 127.0.0.1>nul 这种延时方式不论 x 值大与小误差基本相差不多,可以接受。 ping -n x -w y 0.0.0.1>nul 这种延时方式,延时的时间越长误差越大,甚至会大到离谱,不可以接受。 所以建议尽量不要用第二种方法。 另外关于 ping/n 1 127.1 可以看看这篇文章。 http://biz.chinabyte.com/255/2012255.shtml 补充一点,作者没有提到以零开头数字地址的识别如:ping 0123.1.1.1,其中以零开头的数字 0123 是会按 8 进制解析的,等效于 ping 83.1.1.1。 |
|
| 第13楼 willsort | 发表于 2005-12-04 21:20 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
Re 无奈何:
关于 ping 的延时问题,我最后得出的结论,也是采用3.1,而不采用3.2。 方案3.2至少存在以下问题: 1、ping 发送报文时似乎有一定的延时,而这个延时并非固定的事我曾提到的500毫秒,而会随网络环境和系统环境发生变化。昨天的测值大约是200~300ms,今天则高一些,是400~500ms。 2、ping 的 -w 超时特性需要更多的前提条件,我尝试将我的本地连接禁用后,超时未起作用。 至于,你所提到的延时越长,误差越大问题,那可能是因为你通过 x 调节延时大小,可以通过调节 y 值(单位:毫秒)达到与方案 3.1 相类似的延时精度。 参考链接: 批处理编程的异类——时钟(Clock) http://www.cn-dos.net/forum/viewthread.php?tid=8905#pid54227 |
|
| 第14楼 无奈何 | 发表于 2005-12-05 00:06 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
:to willsort
x 与 y 的值我都调节过,延时长时尽量增大 y 值,延时短时尽量减小 y 值,倒是可以获得小的误差,但是时间换算比较麻烦。 |
|
| 第15楼 willsort | 发表于 2006-01-10 15:03 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
下文转自本站解答室:
http://www.cn-dos.net/forum/viewthread.php?tid=12892#pid95281 关于 HDKP 的几点技术探讨 ============================================================================ 作者:Will Sort 日期:2005-04-22 版本:1-20050505 关键词:HDKP, %comspec%, 命令解释器, drive check, 磁盘检查, 命令行循环 摘要:对 HDKP 磁盘检查和磁盘遍历的在算法和细节上的相关讨论 ---------------------------------------------------------------------------- 背景 全名:Hard Drive Killer Pro 版本:通行版本为 4.0(包括 bat 版和 bat 压缩成的 exe 版),最新版本 5.0beta 作者:Munga Bunga(澳大利亚) 日期:4.0 版最晚成于2001年5月 平台:据原作者声称,此程序可以工作于 DOS/Win3.x/9x/NT/2000 等系统中,适用于 世界上 90% 的电脑,彼时还没有 XP 和 2003 用途:毁掉或者说“清洗”电脑上所有硬盘、软盘和闪盘的所有数据。当然,因其历史 悠久,当前流行的大部分杀毒软件都可将它杀除。 ---------------------------------------------------------------------------- 序言 我最早在《批处理简单教程》中看到这篇转贴的批处理程序,教程作者在精彩程序 示例中将此程序列为压轴之作,当时因为我对一切带有所谓 Killer/Hacking 等字眼的 程序都抱有相当的敌意,所以当时只是草草瞥了两眼,并没有细看。后来,我又在“联 合 DOS论坛”中见到“神仙贝贝”兄发出的帖子中转贴了这个程序,不过基于类似 的原因,我仍然只是翻看了一下有无值得留意的回复,随后顺手关闭了它,以至于后来 Climbing 兄的邀请也没有看到。 4 月中旬我开始翻看“联合 DOS论坛”中关于批处理的旧帖,数次在 Climbing 兄 被置顶的精华帖索引中看到“仔细学学”的建议,终于又点开了“神仙贝贝”的老 帖,此时早已有 wangsea兄将注释的工作漂亮的完成,我的任务就只是简单的享受他人 的劳动果实了。 但是,遗憾的是,这篇程序里出现了太多的问题和漏洞。有些问题,比如那个无效 的格式化开关 /autoSample 和 :Sampledrv,显然都并非原作者的笔误,而像有心人或 者有心的程序特意修改的;另外一些问题,比如 dedecated 和 elapse,就不知是澳大 利亚的方言还是作者的无心之失了;剩下的一下问题,则可以肯定主要的责任人就是作 者本人。 当然,为了讨论的公允和普适,我找到了这个程序的原始链接并试图下载,可 是下载失败,我又尝试了其他几个方法,但找到的版本都与“神仙贝贝”的并无不同。 最后,我决定仍然采用后者作为讨论的基础,所以我讨论的只是代码的得失,而非作者 的得失。 ---------------------------------------------------------------------------- 正文 无可否认的是,程序中确实使用了一些高级技巧,这些技巧最主要的体现就是磁盘 检查程序(drivechk.bat),但需要注意的是, drivechk.bat 并非作者本人原创,它 的原作者是 Tom Lavedas,这也正是作者“Except for”的原因。但是,可能作者 并没有透彻理解这个程序,只是进行了一些简单的改动,也可能作者引用的是 Lavedas 早期的程序,所以这段代码存在着一些问题。 下面是程序中动态生成 drivechk.bat 的一段 echo @echo off >drivechk.bat echo @prompt %%%%comspec%%%% /f /c vol %%%%1: $b find "Vol" > nul >{t}.bat %comspec% /e:2048 /c {t}.bat >>drivechk.bat del {t}.bat echo if errorlevel 1 goto enddc >>drivechk.bat 此段的目的是将下面的代码写入 drivechk.bat 之中。其过程 wangsea 兄已经分 析过,我不再细述。 %comspec% /f /c vol %1: | find "Vol" > nul if errorlevel 1 goto enddc 第一,“echo @echo off >drivechk.bat”一句不是必须的。因为 drivechk.bat 是一个动态生成的被调程序,它在被 call 时,会继承主调程序的 echo off 状态。 只有用 %comspec% /c 调用时,“echo off”才可能被需要,因为 %comspec% /c 会创建一层新的命令解释环境,在这个新环境中 echo 状态会被复位。也正因此,程序 才能通过 %comspec% /e:2048 /c {t}.bat 获得被修改的命令行提示符,它就是要写入 drivechk.bat 的语句。 第二,第二行中的“%%%%comspec%%%%”完全可以改为“%comspec%”。“%%%%”的 作用是延迟 %comspec% 的替换,使得 %comspec% 直到执行 drivechk.bat 时才被替换 为命令解释器的路径;但是这样是没有必要的,因为被调的 drivechk.bat 和主调程序 必定是运行在相同的环境下,所以替换的迟或早并没有什么分别。 而且,我建议直接将 %comspec% 改为 command 。因为在 NT 类的命令行环境中, %comspec% 通常指向 cmd.exe ,它与 command.com 有很多不同,比如在非英文系统中 的代码页不同,导致 find "Vol" /c 失败。而在早期的 MS-DOS 环境中, %comspec% 也有可能指向 NDOS 等非标准的命令解释器,它们的开关参数以及执行输出都可能导致 %comspec% 一句失败。而直接使用 command 最大的问题,就是它不处于当前路径或者 %Path% 路径中,但那几乎是不可能的。 第三,“find "Vol" > nul”应该是“find "Vol" $g nul”,否则“> nul”将不 能写入 drivechk.bat ,从而可能在调用 drivechk 时造成 find 的消息“泄露”;而 在程序调用时,作者试图通过“call drivechk.bat %%a >nul”来避免了这个隐患,但 是他可能不清楚这个“>nul”对于 call 批处理是无效的。 只有通过 %comspec% /c 来调用批处理,其输出才能被重定向或被管道传递。但即 便如此,执行 vol %1:可能有一些输出仍然无法被屏蔽,比如访问了不存在或未准备的 盘所产生的错误消息,因为它所使用的是错误设备输出,而并非标准控制台,所以不通 过管道被传递。解决办法是在 %comspec% /c 的前后加上一对 ctty nul 和 ctty con 语句。但是, ctty 只在 MS-DOS 和 9x 命令行被支持,在 XP 等 NT 类命令行 ctty 被取消了。在此类环境中,只能通过 2> nul 重定向错误消息。 第四,“if errorlevel 1 goto enddc”忽略了很多问题。在 MS-DOS 或者 9x 命 令行中用 vol 访问存在但未准备好的盘,会有 Vol 信息输出,但程序此时并不会跳转 到结束;另外,就是可能访问到只读性的光盘或闪盘,也会有 Vol 信息输出。 所以,程序为了补救者两个缺陷,才在后面使用了 dir | find "bytes" 检测准备 的准备情况,用 dir | find "0 bytes" 再检查只读的光盘。但被锁定的闪盘仍然无法 正确判断,可能在程序完成时,闪盘的锁定功能尚不常见吧。 检测磁盘可读的语句也可以替代以 dir %1:\nul|find "\" ,而检查磁盘可写可以 使用 copy /y _writed_.tag %1: 和 if exist %1:_writed_.tag 来判断,当然这 些语句仍然都需要在 %comspec% /f/c 的外壳中运行。但是,仍然有些我们想不到的问 题,比如我在虚拟PC的共享盘中只能创建和修改文件,但却不能删除它。其他诸如网络 盘、内存虚拟盘等等,我没有对它们做更为细致的讨论。在这些细节上,专业程序也许 做得更好也不一定。 第五,程序中还有一个较简单的技巧,就是在 :Sampledrv 中磁盘的遍历。对于使 用 For 语句进行循环式的遍历,可能是批处理编程的惯例,然而这个惯例在某些情况 下可能并不是最优的。 事实上,在很早的时期,就有人使用更为灵活的命令行循环来处理很多 For难以解 决的问题。比如在 do 后面有多条语句时,我们必须将这些语句放在批处理中被 call 调用,但是 for的特性决定了它运行时的多次重复调用,而命令行循环的优越性在于它 只需要 call 一次,剩下的只是程序内部的 shift和 goto 。这节省了相当多的性能, 因为 call 远比 shift和 goto 占用更多的性能资源。 第六,我们讨论 drivechk.bat 动态生成的必要性。这里并不是说 drivechk.bat 的必要性,而是说动态生成的必要性。我们可以猜测,程序之所以要费尽周章地动态生 成这段代码,而不是把它静态地嵌入在主程序中,其主要目的是可以利用它进行磁盘检 查的循环遍历。然而,可能作者并没有注意或者意识到,使用静态代码也可以完成同样 的任务。这意味着整个程序在写入 drivechk.bat 上所绕的所有的弯路都是不必要的, 我们完全可以找到一条更直接简短的道路。 将程序所需要多次利用的代码作为一个模块嵌入到自身之中,然后再反复调用这个 模块即可达成与调用动态代码相似的效果。模块的通俗化理解就是以一个标签起始,以 goto end结束的一整段代码,而调用这个模块之需要配合使用 call %0 : lablename 和 if "%1"==":" goto %2 即可。 主调程序的结构 CODE: ... :: Call 型调用自身 call %0 : labelname ... :: Goto 型调用自身 %0 : lablename ... :: Call 型调用其他Bat call bat_name : labelname ... :: Goto 型调用其他Bat bat_name : lablename ... 被调程序(可能也是主调程序)的结构 CODE: @echo off if "%1"==":" goto %2 ... :labelname :: 模块的代码段 ... goto end ... :end ---------------------------------------------------------------------------- 结语 我写作此文的目的,正如我在摘要中所提到的,是试图探讨关于磁盘检查和命令行 循环的一些技术特性和细节,而并非是为 HDKP 或者类似的非善意程序提供技术支持。 关于 HDKP 的编写目的,我个人仍然持反对态度。此程序大概正如作者所希望的,只有 对“a very special person that does not want to be named”才具有实用性。对于 我来说,它仅仅是一个技术和构思的不完善结合体。 我知道早已经有专业的第三方程序可以实现磁盘检查的功能,比如 dready.com 。 但是,作为批处理编程的一种技术门类,讨论它仍然是有益的,它可以帮助我们更加深 刻地理解系统工作原理,并且熟悉我们所工作的环境。另外,作为批处理来说,不依赖 于第三方程序,仍然有着相当的优势和价值。 ---------------------------------------------------------------------------- 参考: 01. 希望有哪位朋友能给这个批处理文件写一份完整的注释 http://www.cn-dos.net/dosbbs/dispbbs.asp?boardid=9&id=12892 02. DOS联盟论坛解答室精华帖索引 http://bbs.cn-dos.net/dispbbs.asp?boardid=9&id=13226 03. Hard Drive Killer Pro (HDKP) - The Hackology Network http://www.hackology.com/programs/hdkp/ginfo.shtml 04. Safely Testing the Status of All Types of Drives - Tom Lavedas http://www.pressroom.com/~tglbatch/testdrv.html 05. Avoiding Drive Not Ready - alt.msdos.batch http://groups-beta.google.com/group/alt.msdos.batch/browse_thread/thread/ df0213182e13de5b/fa2abe726f972567?q=%22:_end%22+label+name&rnum=2&hl=en ============================================================================= |
|
| 1 2 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |