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

[原创] 趣味统计:批处理脚本中的数字

本帖最后由 CrLf 于 2016-1-6 17:31 编辑

提示:注意描述语句中“字节”、“字符”的区别,字符根据代码页的不同,在 ansi 编码里可能为 1~2 字节长度。

【0】
  1. set /a 里直接通过变量名由 set 解释变量时,空变量名或变量值不为合法数字的变量都被理解为 0
  2. for /l 会将参数中不为有效数字的项和缺失的项理解为 0,典型例子为 for /l %%a in () do echo 无限循环
复制代码
【1】
  1. 0D 0A 这一对回车换行符在预处理时将被理解为 1 个 0A 字符
  2. for /f 中的 skip 至少等于 1
  3. pause 可接受任意 1 个字符为输入
复制代码
【4】
  1. 许多命令默认只判断后缀名的前 4 字节(含 . 在内),所以使用 dir、type、findstr 等命令对 *.txt 通配时无法区分 a.txt 和 a.txtt,当通配条件不使用 * 或后缀名超过 4 字节时将自动改用完整匹配
复制代码
【8】
  1. 短名最长 8 字节
  2. 制表符(tab)宽度为 8 字节
  3. more 会将 tab 转化为等宽度的空格(默认 8 个字节)
复制代码
【10】
  1. cmd 最多支持同时直接操作 10 个句柄:句柄0 标准输入,句柄1 标准输出(约定俗成),句柄2 标准错误(亦然),句柄3~9 由命令自定义,共 10 个句柄,但句柄备份证明句柄9 之后至少还存在一个无法直接操作的隐藏句柄10
复制代码
【32】
  1. setlocal 最多嵌套 32 层(本质是最多允许用 setlocal 创建 32 张临时变量表),call 可以在调用过程中将层数暂时归零,等子过程退出后恢复
  2. for /f 的 tokens 设置项最多支持 32 节,但是无论是否声明 * 都必须为其保留一个位置,所以若要用全 32 节,必须声明为 tokens=1-31*(无法直接声明超过 31 的节)
  3. cmd 计算时以 long int 的数据类型进行操作,其中的数字由 32 位组成
复制代码
【512】
  1. 标签被调用时,将一行一次性读入 512 字节
复制代码
【1024】
  1. set /p 最多容许 1024 个字节长度,但若第 1023、1024 字节处所取得的两字节不是一个完整的宽字符时,最多容许 1023 字节
复制代码
【4096】
  1. sort 命令的 /rec 开关默认值为 4096,即默认支持对短于 4096 字符的行进行排序(此设置可更改)
复制代码
【8153】
  1. 64 位 Windows7 中,cmd 的单条命令行长度上限为 8153 字符
  2. 有趣的是,在 xp 的 cmd 中,该上限为 8154 字符
复制代码
【8192】
  1. cmd 从脚本中一次读入 8192 字符
  2. 变量长度最长为 8192 字符,包括变量名、等号和内存中的变量分隔符 00
  3. 若因内存泄露导致变量末尾的 00 丢失,使用 %var% 或 !var! 引用变量时只会读取 8192 字符长度
复制代码
【32767】
  1. %random% 的取值上限
复制代码
【65535】
  1. cmd 所能使用的内存空间上限为 65536K,但是每次 call 都能额外领取空间额度。
  2. sort 支持的行长度上限为 65535 字符
  3. more 执行时一次最多操作 65535 行
  4. debug 支持的段空间为 65535 字节(因为它是 16 位的 com),所以仅支持小于 64K 的文件
复制代码
【-2147483648 与 2147483647】
  1. cmd 中数值的上下限,其实就是 long int 支持的计算范围
复制代码
4

评分人数

    • 回家路上: 拜倒技术 + 1
    • qzwqzw: 看来还是版主的权限大,技术分我只能加1分: ...技术 + 1
    • cjiabing: 好多人像我一样都需要补补数学PB + 6 技术 + 3
    • find: 感谢分享技术 + 1

回复 4# qzwqzw


    感谢指正,原内容已按提示修正

TOP

回复 9# qzwqzw


    感觉似乎是通病,测试了几个常用的支持文件通配符的命令(包括已测试的外部命令)都存在这个问题
    修改了一点,麻烦再把关下。

TOP

本帖最后由 CrLf 于 2012-8-17 04:45 编辑

回复 11# Demon


    从测试的表象来看确实是字符:
  1. Const num = 8192
  2. Const text = "测"
  3. '比较奇特的是,在 xp 环境下测试时,
  4. '如果 text="t",则 cmd 遇到超过 8192 字符长度的行将无提示退出
  5. '如果 text="测",则 cmd 会对字符串进行截断,且不会因为超长而退出
  6. '没有细究宽字符与单字节字符共存的复杂关系下有何异同
  7. 'win7 不存在出错退出的现象,且上次曾和兄台讨论过得知 win7 下的 cmd 会分段读取超长行的内容(不好意思,忘记是哪个帖了,链接就不贴了)
  8. Set fso = CreateObject("Scripting.FileSystemObject")
  9. str = "echo " & String(num,text)
  10. With fso.CreateTextFile("test.bat",True)
  11.     .Write "@echo off" & vbCrLf
  12.     .Write str
  13.     .Close
  14. End With
  15. Set ws = CreateObject("Wscript.Shell")
  16. out = ws.exec("cmd /c test.bat").stdout.readall
  17. MsgBox "strlen=" & Len(str) & vbCrLf &_
  18.        "outlen=" & Len(out) & vbCrLf &_
  19.        out
复制代码
至于 cmd 一行具体读入的数量...我是听另一位大牛说的,这是他 hook 出来的数据,从纯批的测试结果看来也是如此,如果将那个被转为 null 的换行符计算在内刚好 8192,不算的话则是 8191

变量末尾的 00 丢失现象:http://bbs.bathome.net/redirect. ... 3&fromuid=30406
最早提及这个现象的帖子不知道在何处,我也只懂得用 debug 看内存来旁敲侧击猜测成因,不知其本质何在。至于内存泄露一说,时隔数月已经印象模糊了,只记得那时在讨论 for /f 的 bug,不记得写此贴时是否是在援引他人观点,也可能是本人当时思维混乱了吧...

当时听 qzw 说到内存泄露的帖子是:
http://bbs.bathome.net/viewthread.php?tid=15748
后来一搜发现早有类似的先例(题外话:这 tid 果然早啊...):
http://bbs.bathome.net/viewthread.php?tid=3614
其实那个帖子肯定也不是 first,印象中听很多前辈说 for /f usebackq 是经常出这种问题的,不过我是没碰到过的,也许因为他们是 xp 系统?

TOP

返回列表