Board logo

标题: [其他] echo 最佳用法考 [打印本页]

作者: CrLf    时间: 2012-8-3 15:06     标题: echo 最佳用法考

本帖最后由 CrLf 于 2012-8-3 19:12 编辑

运行测试代码(需要 ascmap.cmd 函数文件:http://bbs.bathome.net/thread-12347-1-1.html):
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. call ascmap $
  4. cd .>enable.txt
  5. for /l %%a in (0x20 1 0x7f) do (
  6. echo "!$:~%%a,1!"
  7. %comspec% /v:off /c "echo!$:~%%a,1! test" 2>nul|findstr " test" &&echo %%a=%%a>>enable.txt
  8. )
  9. pause
复制代码
测得 echo 可用参数分隔符如下(格式:"[字符]"=[ASC]):
  1. " "=32
  2. "("=40
  3. "+"=43
  4. ","=44
  5. "."=46
  6. "/"=47
  7. ":"=58
  8. ";"=59
  9. "="=61
  10. "["=91
  11. "\"=92
  12. "]"=93
复制代码
以下为一些测试结论:
1、echo 后跟空格的用法通用性最差,不兼容空行或仅含空格的行、不能直接显示 /?、on 和 off:
  1. echo
  2. echo /?
  3. echo on
  4. echo off
复制代码
2、而 ; , = 同属于 cmd 中的默认分隔符,虽然是对空格的改进,却仍无法显示 /?:
  1. echo;/?
  2. echo,/?
  3. echo=/?
复制代码
3、echo 后跟 .、:、\、+、[ 或 ] 时,能将参数理解为消息,但是会触发对文件的搜索,所以效率会降低
(参考:http://bbs.bathome.net/redirect. ... 2&fromuid=30406
与:http://bbs.bathome.net/redirect.php?tid=18352),并有可能打开路径相吻合的文件
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (";" . : \) do (
  3. (set timea=!time!
  4. for /l %%b in (1 1 10000) do echo%%~a
  5. call :时差 !timea! !time!)>nul
  6. echo 运行 10000 次 echo%%~a 的用时为: !时差!
  7. )
  8. pause
  9. :时差
  10. for /f "tokens=1-8 delims=:. " %%a in ("%*") do (
  11. set /a "时差=(((%%e-%%a)*60+1%%f-1%%b)*60+1%%g-1%%c)*100+1%%h-1%%d"
  12. )
复制代码
4、如此排除,就只剩下了 (,经测试,其各方面兼容性均达标,唯一的遗憾大概就是会影响编辑器中的括号匹配:
  1. setlocal enabledelayedexpansion
  2. echo(
  3. echo(/?
  4. echo(on
  5. echo(off
  6. echo(!tmp:\=!
复制代码
结论:以后还是用 echo( 好了,丑是丑了点,胜在通用性。


附原第 4 点:
------------------------------------------------------------------------------------------------------------------
4、echo 后跟 .、:、\、+、[ 或 ] 时会十分离奇地在特定情况下(比如参数中无空格)禁用对延迟变量中的变量替换进行解释:
  1. setlocal enabledelayedexpansion
  2. echo.!tmp:\=!
  3. echo:!tmp:\=!
  4. echo\!tmp:\=!
  5. echo+!tmp:\=!
  6. echo[!tmp:\=!
  7. echo]!tmp:\=!
复制代码
------------------------------------------------------------------------------------------------------------------
本贴 3楼 demon 猜测这其实是命令被优先理解为路径导致的,经证实确实如此,解决方法是转义 ! 号对中的默认分隔符:
  1. echo\!tmp:\^=!
复制代码
与第3点本质上有所重复,故从正文中移除。
作者: loquat    时间: 2012-8-3 15:42

版主研究很深,小弟还没有体验到这个深度
作者: Demon    时间: 2012-8-3 15:59

本帖最后由 Demon 于 2012-8-3 16:57 编辑
  1. for /l %%i in (1 1 1) do (
  2.     echo((1+2)*3=9
  3.     echo(round bracket is best?
  4.     echo(I don't think so.
  5. )
复制代码
http://demon.tw/reverse/cmd-internal-parser.html

http://demon.tw/reverse/cmd-internal-echo.html

简单说几句吧,除了空格" "、等号"="、逗号","、分号";"以及你给出的左括号"("外,其他符号都会对文件进行搜索。

至于你提到的第4点,也没什么离奇的,不要忘了等号"="在一般情况下也是分隔符,
  1. echo+!tmp:\=!
复制代码
CMD在解析(Parse)时会将等号前面的echo+!tmp:\当成命令,而后面的=!当成命令的参数。

显然echo+!tmp:\并不是有效的内部命令,这时CMD会当成外部命令进行文件搜索(效率降低),然而依然无法找到,这时会对命令进行修复(Fix)。

但是如果ENABLEDELAYEDEXPANSION的话,变量延迟拓展是在命令修复之前进行的,CMD会分别对echo+!tmp:\命令和它的参数=!进行变量延迟拓展,

很显然得到的命令是echo+tmp:\,参数是=,修复后的命令是echo,参数是+tmp:\=,最后echo的输出是tmp:\=

结合上面的情况来看,echo并不存在所谓的最佳用法,需要根据具体情况选择,我的建议是一般情况下使用逗号","(出于效率),在需要输出/?开头的字符串时使用加号"+"。
作者: CrLf    时间: 2012-8-3 17:13

本帖最后由 CrLf 于 2012-8-3 17:32 编辑

回复 3# Demon


    老兄对第 4 点的解释确实很有道理,恍然大悟,实际原因大约就在于此,这和 echo.bat 的原因一致:
  1. echo.bat
  2. ::先对文件名进行匹配,找不到时再以 echo 命令解读
  3. echo pause>echo.bat
  4. echo.bat
  5. ::由于找到了相应的文件,所以执行的是 echo.bat 而非 echo 命令
  6. echo test
  7. ::虽然 bat 可以只靠文件名来调用,但是内部命令例外
复制代码
括号的错误匹配一向是发生在 ) 的多余和缺失上,与 ( 无关,所以括号对中的 echo((1+2)*3=9 只要改成 echo((1+2^)*3=9 就能正确运行了,所以并非 "echo( 通用性最强" 的反例。

另外,不知为何在同样需要搜索文件的前提下,+、[、] 的效率要远高于 .、:、\,反而与 "echo " 接近?
莫非  .、:、\ 效率低下的原因并不是对文件匹配?
测试代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (" " . : \ + [ ]) do (
  3.         (set timea=!time!
  4.         for /l %%b in (1 1 10000) do echo%%~a
  5.         call :时差 !timea! !time!)>nul
  6.         echo 运行 10000 次 echo%%~a 的用时为: !时差!
  7. )
  8. pause
  9. :时差
  10. for /f "tokens=1-8 delims=:. " %%a in ("%*") do (
  11.         set /a "时差=(((%%e-%%a)*60+1%%f-1%%b)*60+1%%g-1%%c)*100+1%%h-1%%d"
  12. )
复制代码

作者: CrLf    时间: 2012-8-3 21:35

本帖最后由 CrLf 于 2012-8-3 21:39 编辑

回复 5# Demon


    貌似我这帖子没有说过 echo. 具有通用性,只说过 echo( 在同条件下是十二种方案中通用性最强的一种,所以个人认为这是 echo 的最佳用法。
  那个转义的例子只是为了说明使用时可以将特殊字符转义避免错误解析,稍作引申罢了,若按老兄的角度来无限放大通用性的范围,那没有任何一种办法能在不转义的情况下 echo &、| 等 特殊字符,也没有办法 echo 超过 8187 字符(8192-5)长度的字符串了
作者: forfiles    时间: 2012-8-3 23:34

不懂帮顶
当需要用一个BAT动态生成另外一个BAT的时候,估计echo(比较纠结。
作者: CrLf    时间: 2012-8-4 17:29

回复 6# forfiles


    见 4 楼观点:
括号的错误匹配一向是发生在 ) 的多余和缺失上,与 ( 无关

作者: Demon    时间: 2012-8-5 00:19

回复  Demon


    老兄对第 4 点的解释确实很有道理,恍然大悟,实际原因大约就在于此,这和 echo.bat ...
CrLf 发表于 2012-8-3 17:13


更正一下《批处理技术内幕:ECHO命令》的错误,

由于当时没有分析文件搜索的CALL(太复杂懒得跟踪),错误的认为它们的搜索过程都是一样的,在简单分析了一下分析文件搜索的过程之后,发现并不是如此,

虽然+/[]:.\都会调用文件搜索的CALL,如果命令中存在冒号:或者反斜杆\,处理的方法与不存在时是不一样的。

另外,在搜索开始之前斜杆/(即Unix路径分隔符)会被替换成反斜杠\,故斜杆和反斜杆效果是一样的。

具体的处理过程比较复杂,就不展开了,具体到echo而言,echo/ echo: echo\都不会进行实际的文件搜索,只是会调用一些无关痛痒的函数,对效率的影响基本是可以忽略的。

而echo+ echo[ echo] echo.会对工作目录与%PATH%中的目录进行搜索,速度自然会比较慢。

但是用你给出的测试代码测试出来的结果似乎并不符合上面的结论,原因不明,我用的是下面的测试代码:
  1. Set fso = CreateObject("scripting.filesystemobject")
  2. set WshShell = CreateObject("wscript.Shell")
  3. s = "(=,;/\:+[]."
  4. For i = 1 To Len(s)
  5.     c = Mid(s, i, 1)
  6.     h = Hex(Asc(c))
  7.    
  8.     With fso.OpenTextFile(h & ".bat", 2, True)
  9.         .WriteLine "@echo off"
  10.         .WriteLine "set s=%time%"
  11.         For j = 1 To 100
  12.             .WriteLine "echo" & c & ">nul"
  13.         Next
  14.         .WriteLine "set e=%time%"
  15.         .Write "echo echo" & c & " %s% %e%>" & h & ".txt"
  16.     End With
  17.    
  18.     WshShell.Run h & ".bat", 0, True
  19.    
  20.     With fso.OpenTextFile(h & ".txt")
  21.         a = Split(.ReadLine, " ")
  22.     End With
  23.    
  24.     WScript.Echo a(0), TimeDiff(a(1), a(2))
  25.    
  26.     fso.DeleteFile h & ".bat"
  27.     fso.DeleteFile h & ".txt"
  28. Next
  29. Function TimeDiff(s, e)
  30.     t = DateDiff("s", CDate(Left(s, 8)), CDate(Left(e, 8)))
  31.     t = t * 1000 + (Right(e, 2) - Right(s, 2)) * 10
  32.     TimeDiff = t
  33. End Function
复制代码

作者: CrLf    时间: 2012-8-5 14:45

本帖最后由 CrLf 于 2012-8-5 15:14 编辑

回复 8# Demon


试了下貌似测试结果浮动很大...建议使用 10000 以上的循环次数
另外建议在测试代码中这样:
(for /l %%a in (1 1 100000) do echo.)>nul
因为复合语句只需要一次 ReadFile 和后续预处理,对整个复合语句使用 >nul 也是同理,排除干扰后用时骤减。

比较奇怪的是,/ 虽然会被处理为 \,可用时却很低...
作者: plp626    时间: 2012-8-5 20:11

  1. ->(cff "echo,", "echo;", "echo=", "echo:", "echo/", "echo\", "echo[", "echo]", "
  2. echo." )|findstr .
  3. Microsoft Windows XP [版本 5.1.2600]
  4. Genuine Intel(R) CPU           T1600  @ 1.66GHz
  5. NUMBER_OF_PROCESSORS=2
  6. ------------ CMD指令测试 -------------
  7. "echo,"                               @  74457.5 Hz
  8. "echo;"                               @  72267.6 Hz
  9. "echo="                               @  68252.7 Hz
  10. "echo:"                               @  39622.5 Hz
  11. "echo/"                               @  84727.5 Hz
  12. "echo\"                               @  29233.3 Hz
  13. "echo["                               @  84727.5 Hz
  14. "echo]"                               @  81903.3 Hz
  15. "echo."                               @  26691.3 Hz
复制代码

作者: Demon    时间: 2012-8-5 20:59

回复  Demon


试了下貌似测试结果浮动很大...建议使用 10000 以上的循环次数
另外建议在测试代码中这 ...
CrLf 发表于 2012-8-5 14:45


我当然知道用for的话可以节省IO的时间,但可惜的是for并不能正确的测试出结果,因为for中的echo根本不会触发文件搜索!

4楼测试代码得到的结果之所以+/[]的效率要高于:.\,是因为如果ENABLEEXTENSIONS的话,echo: echo. echo\会多调用一次GetFileAttributes函数,这点我在《批处理技术内幕:ECHO命令》已经说得很清楚了。

对比一下这两段代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (+ / [ ] : . \) do (
  3.     (set timea=!time!
  4.     for /l %%b in (1 1 10000) do echo%%~a
  5.     call :时差 !timea! !time!)>nul
  6.     echo 运行 10000 次 echo%%~a 的用时为: !时差!
  7. )
  8. pause
  9. :时差
  10. for /f "tokens=1-8 delims=:. " %%a in ("%*") do (
  11.     set /a "时差=(((%%e-%%a)*60+1%%f-1%%b)*60+1%%g-1%%c)*100+1%%h-1%%d"
  12. )
复制代码
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (+ / [ ] : . \) do (
  3.     (set timea=!time!
  4.     for /l %%b in (1 1 10000) do setlocal disableextensions&echo%%a&endlocal
  5.     setlocal enableextensions
  6.     call :时差 !timea! !time!)>nul
  7.     echo 运行 10000 次 echo%%~a 的用时为: !时差!
  8.     endlocal
  9. )
  10. pause
  11. :时差
  12. for /f "tokens=1-8 delims=:. " %%a in ("%*") do (
  13.     set /a "时差=(((%%e-%%a)*60+1%%f-1%%b)*60+1%%g-1%%c)*100+1%%h-1%%d"
  14. )
复制代码
我上面给出的VBS测试代码虽然大部分时间都浪费在了IO上面,但是可以认为IO时间基本相同,echo+ echo[ echo] echo.花的时间明显高于其他的:
  1. echo( 70
  2. echo= 70
  3. echo, 60
  4. echo; 70
  5. echo/ 80
  6. echo\ 90
  7. echo: 80
  8. echo+ 680
  9. echo[ 670
  10. echo] 720
  11. echo. 790
复制代码

作者: Demon    时间: 2012-8-7 09:31

echo最多可以输出8191个字符,而不是8187个。
作者: qzwqzw    时间: 2012-8-7 10:10

本帖最后由 qzwqzw 于 2012-8-7 10:52 编辑

xp sp3下测试
确认echo最多只能输出是8186个字符
如果echo行后有回车则最多输出8185个字符
加上echo空格和结束符0
算起来正好是8192个
不知道各位的测试环境的代码是什么?
  1. @echo off
  2. echo 8195字符测试(行尾有回车符)
  3. echo 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
  4. echo 8196字符测试(行尾没有回车符)
  5. echo 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
复制代码

作者: Demon    时间: 2012-8-7 10:26

xp sp3下测试
确认echo最多只能输出是8186个字符
如果echo行后有回车则最多输出8195个字符
加上echo空格 ...
qzwqzw 发表于 2012-8-7 10:10


Windows 7 Ultimate Service Pack 1 英文原版
  1. Dim fso
  2. Set fso = CreateObject("scripting.filesystemobject")
  3. With fso.OpenTextFile("1.bat", 2, True)
  4.     .WriteLine "@echo off"
  5.     .WriteLine ">1.txt echo " & String(8192 * 2, "#")
  6. End With
  7. Dim WshShell
  8. set WshShell = CreateObject("wscript.Shell")
  9. WshShell.Run "1.bat", 0, True
  10. WScript.Echo Len(fso.OpenTextFile("1.txt").ReadAll)
复制代码

作者: qzwqzw    时间: 2012-8-7 11:33

本帖最后由 qzwqzw 于 2012-8-7 11:38 编辑

确实是环境的问题
在我的xpsp3/03 r2 sp1下
你的vbs脚本只能测试到8178个字符(不计回车换行符)
所以讨论的前提是统一测试环境


另外,发现通过变量中转的方法可以让echo输出更多的字符
使用%%可以最多输出8188个字符
如果行尾有回车换行符则只能输出8186个字符
使用!!可以最多输出8190个字符
但是两种方法在极限情况下都存在“吞吃”回车换行符的问题
  1. @echo off
  2. set v=12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
  3. setlocal EnableDelayedExpansion
  4. echo !v!1234567890
  5. echo %v%12345678
复制代码

作者: qzwqzw    时间: 2012-8-7 11:40

从以上测试可以看出
echo能够输出的最大字符数
不仅取决于echo命令的缓冲区
同时取决于cmd的词法分析缓冲区
以及其它各种临时缓冲区的长度
作者: CrLf    时间: 2012-8-7 15:29

本帖最后由 CrLf 于 2012-8-7 18:22 编辑

回复 14# Demon


    win7 下测试无误,可是我无法理解 win7 下为何能直接 echo 8191 个字符,按理说就算是 echo 空行也要至少需要五个字符,cmd 不是一次性读入 8192 字节的吗?那么在 win7 下为何能从脚本一次性读入至少 8196 个字符?   
    顺便向老兄请教两个疑问,本地 vbs 有没有办法操作现存的 IE 页面,就像操作用 IE.Navigate 打开的页面那样?第二个问题,本地 vbs 该怎么调用 htm dom 中的脚本函数?

回复 16# qzwqzw


    题外话:发现变量值的上限不是以往认为的 8190 字符,而是 8191...
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1 1 12) do set a=!a!!a!a
  3. ::此时变量 a 的值长度为 4095
  4. set a=!a!!a:~1!
  5. echo !a:~8188!
  6. ::此时变量 a 长度为 8189,这是常见赋值办法下的极限
  7. set;=!a!;
  8. echo !;:~8188!
  9. ::使用 ; , 这两个分隔符作为变量名可以“偷”一个字符长度
  10. set[=!;![
  11. echo ![:~8188!
  12. ::使用 [ ] + \ . 作为变量名居然还可以再偷一个字符长度...
  13. pause
复制代码

作者: qzwqzw    时间: 2012-8-7 18:00

这说明win7的cmd的各种命令行缓冲区肯定有部分扩大了
只不过echo自己的缓冲区还是那么小而已

本地vbs操作本地html页面可以使用htmlfile对象
一个粗糙的示例
  1. set oDOM = GetObject("D:\页面.html", "htmlfile")
  2. Do Until oDOM.readyState="complete" : WScript.Sleep 200 : Loop
  3. WScript.echo  oDOM.getElementsByTagName("TD")(1).innerHTML
复制代码
set[充分说明cmd的词法分析与调度执行模块的协调存在缝隙
作者: CrLf    时间: 2012-8-7 18:09

回复 18# qzwqzw


    多谢了,getobject 一直不会用,w3school 中的解释语焉不详,还以为不重要...
作者: Demon    时间: 2012-8-8 10:20

不同系统之间的差异真讨厌,无论是XP还是Windows 7的CMD都是一次读入8191个字节,当命令超过8191个字节时,Windows 7会多次读取直到命令结束,但在echo输出之前又会截断为8191个字符;而XP则直接报错(纯属猜想,未验证)。

除了WMI和ADSI中还是少用GetObject的好。
作者: qzwqzw    时间: 2012-8-9 12:09

关于GetObject楼主想的太多了
在保证可以稳定运行且又满足需求的前提下
什么方案都是可以选择的
不需要纠结于一些技术上的细节

而且GetObject多用于WMI和ADSI
也是一种经验之谈
没有什么太强的约束性




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2