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

回复 1楼 的帖子

掉了过引号
@echo off
setlocal enabledelayedexpansion
color 1f
set "var=00000"
for /l %%a in (1 1 10) do set var=!var!!var!
echo !var!
echo 这里可以运行。
pause
color cf
set var=!var:0= 0 !
echo !var!
echo 这无法运行???
pause


set "var=00000"这句里面的00000是字符串常量,set var=!var:0= 0 !里面电脑把它读成了数字,是数据类型不匹配。所以运行不了。改为 set var=!var:“0”=“ 0” 就正常了。!
1

评分人数

TOP

回复 17楼 的帖子

但是微软中文网站在翻译5楼那篇文章的时候,居然照搬原文,也不去修改一下,实在不应该。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复 13楼 的帖子

对于微软说法中(Byte)不准确的说法,我想也是可以理解的。技术的发展或多或少都要局限于当时的环境,当时创建字符编码时我想微软也没有考虑到若干年以后全球关系发展的如此迅速,所以也就出现了90年代又花了几年时间来编写Unicode,作为一个统一的国际化编码标准。并且各个国家地区采用的字符集不一致,对于非Unicode的环境下采用活动代码页来进行编码的转换。兄测试下如下代码:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 10000) do (
  4.   set m=a人!m!||(echo %%a&pause)
  5.   )
  6. pause
复制代码
结果为4095,也就是8190的一半。我们可以理解为8192是按字符算的,但是这确实涉及到我们经过活动代码页936的转换后,环境变量在内存中是如何分配的。比如单字节集中空格表示为20H,而经过转换后单字节字符与双字节字符应该如何统一,按原样表示还是扩充为双字节0020H。对于此我没有研究过,还需要再在网上找一些相关资料。

TOP

回复 10楼 的帖子

对于第5步中的代码,如果改为如下,则可以执行。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 8185) do (
  4.   set a=!a!0
  5.   )
  6. set a=%a:0=1%
  7. echo !a!
  8. pause
复制代码
我也认为和预处理有关,开启变量延迟后,执行到那一句才展开变量,所以set a=!a:0=1!中,把第一个等号右边的理解为一个整体,而set a=%a:0=1%,在执行之前就已经展开,所以 a=%a:0=1%以及右边的%a:0=1%都要满足不能超过最大长度。前面'a'以及'='已经占了2字节。所以%a:0=1%最大为8190字节。其中变量名a、'='、'0'、'1'、标记位各占一个字节,剩下变量a中所包含的字符串最大长度也就是8185了。

TOP

我有没有看错时间,呵呵,各版主辛苦了,颇有研究哈

TOP

回复 13楼 的帖子

可能是当年微软写帮助文档的时候,没有考虑到每个汉字占两个字节^_^
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

如果用echo命令将变量写到文本中,
!m!长度是8190,而文本中的字符是8189个“a”+2字节的回车换行符(CrLn),结果共8191个字节。
!,!长度是8191,而文本中的字符是8190个“a”+1个回车符(Cr),结果也是共8191个字节。

已经讨论过,微软的说法中“字节(byte)”是不准确的,实际可以为字符。
如果把字母a换成汉字比如“人”,则
!m!长度是8190,而文本中的字符是8189个“人”+2字节的回车换行符(CrLn),结果共(8189*2+2)个字节。
!,!长度是8191,而文本中的字符是8190个“人”+1个回车符(Cr),结果共(8190*2+1)个字节,比上面多1个字节。

[ 本帖最后由 zqz0012005 于 2009-2-22 06:47 编辑 ]
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

关于取最大长度的一个题外话(先写在这里,整理时再分开或删除吧)
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 8193) do (
  4.   set,=a!,!||(echo !,!&echo !errorlevel!&pause)
  5. )
  6. pause
复制代码
如果换成以下形式
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 8193) do (
  4.   set,=a!,!
  5.   if !errorlevel! neq 0 (echo !,!&echo !errorlevel!&pause)
  6. )
  7. pause
复制代码
即将||改成errorlevel的形式,结果竟然不同。

这好像是for语句内部errorlevel返回值的问题。以前说过for本身是一个特殊的命令解释程序,但不知这一点有没有讨论过(我以前也发过,但讨论的人不多,我当时的分析也比较混乱,有时间再好好整理一下)。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 7楼 的帖子

至于第2点中推断的结论“变量名和等号都占字节”,可以进一步验证:
随风的一个测试代码
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 10000) do (
  4.   set m=a!m!||(echo %%a&pause)
  5.   )
  6. pause
复制代码
如果把变量名换成逗号“,”,利用命令行的空子,写成如下形式:
set,=a!,!||(echo %%a&pause)
则结果为8191。
逗号有多重意思,一是作为命令与参数之间必要的分隔符,二就是作为变量名。而系统有时对这种多样性处理不完善,最后的结果认为set,=a!,!语句中没有变量名,于是给变量值多分配了一位。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 7楼 的帖子

关于第5点,我认为可能和预处理有关系。
set a=!a:0=1!,预处理时并不展开变量(执行时才进行替换操作),所以输入行长度为该行语句字面长度13。
set a=%a:0=1%,预处理时要先对变量进行展开,展开后的长度显然超过了命令行允许的长度(这个长度应该是8192)。

[ 本帖最后由 zqz0012005 于 2009-2-22 05:22 编辑 ]
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

恩,是笔误啊,谢谢兄指正!

TOP

set m=“a!m!”||
引号笔误吧 应该是 set "m=a!m!"

[ 本帖最后由 随风 于 2009-2-21 19:05 编辑 ]
技术问题请到论坛发帖求助!

TOP

由batman所发代码引申出的变量最大长度问题,以下代码由batman、随风、我共同讨论测试得出,结果也只是提出一个猜想,望大家讨论补充!
1、首先给出随风的一个测试代码
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 10000) do (
  4.   set m=a!m!||(echo %%a&pause)
  5.   )
  6. pause
复制代码
结果为8190,这时可能大家会认为最大长度应该是8190。
2、现在做一个小小的改变,把以上代码中的set m=a!m!||(echo %%a&pause)改为set var=a!var!||(echo %%a&pause)。再次运行,按理说结果应该没影响,可是出乎我们的意料,结果为8188。这是为何?参照batcher给出的资料,可以推出变量名和等号都占字节。
3、现在再做出一个改变,把set m=a!m!||(echo %%a&pause),改为set “m=a!m!“||(echo %%a&pause),再次运行,结果是8188。又困惑了,我们一般来看set "str1=str2"和set str1=str2所达到的效果是一样的。再根据资料The maximum individual environment variable size is 8192bytes。我想着要从环境变量的内存空间分配角度来思考了。环境变量分配的最大空间为8192字节。其中包括变量名、等号、引号(如果有的话)、以及变量所包含的字符。
4、为了更加清晰,对刚才代码增加一些。如下:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 10000) do (
  4.   set a=!a!0
  5. )
  6. if "!a:~8181,1!"=="" echo 8181
  7. if "!a:~8182,1!"=="" echo 8182
  8. if "!a:~8183,1!"=="" echo 8183
  9. if "!a:~8184,1!"=="" echo 8184
  10. if "!a:~8185,1!"=="" echo 8185
  11. if "!a:~8186,1!"=="" echo 8186
  12. if "!a:~8187,1!"=="" echo 8187
  13. if "!a:~8188,1!"=="" echo 8188
  14. if "!a:~8189,1!"=="" echo 8189
  15. if "!a:~8190,1!"=="" echo 8190
  16. if "!a:~8191,1!"=="" echo 8191
  17. if "!a:~8192,1!"=="" echo 8192
  18. if "!a:~8193,1!"=="" echo 8193
  19. pause
复制代码
执行后显示为8189,按照刚才的分析,共占有的字节数:8189+1('a')+1('=')=8191,不是8192。这又是为何?再看下面?
5、batman提供的代码:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /l %%a in (1 1 10000) do (
  4.   set a=!a!0
  5.   )
  6. set a=!a:0=1!
  7. echo !a!
  8. pause
复制代码
上面代码可以正常运行,可是把上面的代码中set a=!a:0=1!改为:set a=%a:0=1%则提示输入过长。这说明开启变量延迟内存中的分配发生变化,到底是什么变化?期待有人来提供一些资料。
6、第四步分析的还差一个字节,我猜想是不是内存自动占用一个固定的标记字节,来标志是否启动了变量延迟以及其他的一些标志。此也期待有心人来完善。
7、这就是我们的初步分析,可以知道的是单个环境变量的最大的内存分配为8192字节(有资料为证),对于这么多字节的如何分配还有待继续探索。欢迎大家一起来讨论!

[ 本帖最后由 lhjoanna 于 2009-2-21 22:44 编辑 ]

TOP

错误信息如下

这里可以运行。
请按任意键继续. . .
输入行太长。
命令语法不正确。

TOP

http://technet.microsoft.com/en-us/library/bb490954.aspx

The maximum individual environment variable size is 8192bytes.

The maximum total environment variable size for all variables, which includes variable names and the equal sign, is 65,536KB.
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表