[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
测试如下代码。复制内容到剪贴板代码:
  1. @echo off
  2. set a=0b0c00a000s&echo %a%
  3. pause
复制代码
保存为bat。运行,你会发现a的值并不是你所想的那样,而是显示echo处于关闭状态。
这是因为CMD命令解释器在读到set a=0b0c00a000s&echo %a%这一条完整的语句时,发现a用%%闭合,是个变量,会把它替换成之前所赋给它的字符串常量,并把它打印出来。而在这条完整的语句之前并没有给a赋值,即是空值。所以才会显示echo处于关闭状态。请理解“一条完整的语句”的意思。
set a=0b0c00a00s&echo %a% 这才是一条完整的语句。
同样的,for语句中给a赋值,然后又在for中引用%a%,在这之前,CMD早就把它替换为空值了,所以你的代码会出错。
如何避免这种出错呢,要用到变量延迟了。
setlocal enabledelayedexpansion 这条语句的意思即是开启变量延迟。它的作用就是要告诉CMD,在读到一条完整的语句时,不要急匆匆地扩展变量。而是在执行复合语句(for语句或if语句中其后用一对圆括号闭合的所有语句称为复合语句,用&或&&连接的也是复合语句。)中的某单条语句之后,再执行变量的扩展,也就是说,这个变量扩展的行为被延后了。在开启延迟之后,在for中给变量a赋值,又在for中引用a,此时,就不应用%%将其闭合了,而是用!!。
你的代码应该是这样。复制内容到剪贴板代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. echo %time%&ping 127.1 /n 5 >nul&echo !time!
  3. pause
复制代码
还要记得,如果在复合语句之外再次引用变量,此时它的值是在复合语句之内最后得到的值。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (100 1 199) do set var=%%a&echo !var:~1!
  3. echo %var%
  4. pause
复制代码
关于变量延迟,搜索一下,多做测试很快就能明白了,我说的很粗糙。
心绪平和,眼藏静谧。

TOP

回复 3楼 的帖子

只说对了一半。
例如说 set xcqkenl=xcqkenl00 &echo %xcqkenl% 则结果显示为%xcqkenl% 而非 xcqkenl00
这句,你是在CMD中这样做的吧,在CMD中显示%xcqkenl% 在批处理中会显示echo处于关闭状态。这就是CMD与批处理的区别,这就要牵扯到cmd的预处理机制了,这东西复杂得很。
关于变量延迟,请记住“即时”这个关键词。
  1. @echo off
  2. ::步骤1
  3. set xcqkenl=xcqkenl00 &echo %xcqkenl%
  4. ::步骤2
  5. set xcqkenl=xcqkenl &echo %xcqkenl%
  6. pause
复制代码
以上代码存为批处理。
步骤1会显示echo处于关闭状态,是因为这条完整的语句之前并没有给xcqkenl赋值,所以会输出这样的结果。
步骤2会显示xcqkenl00,是因为在在步骤一中给它赋的值,并不是步骤2中的值。
要得到即时得到的值。用变量延迟。
  1. @echo off&setlocal enabledelayedexpansion
  2. set a=a&echo %a%
  3. echo %a%
  4. set a=b&echo %a%
  5. set a=c&echo !a!
  6. pause
复制代码
以上,运行时,请注意每条语句的输出结果。
心绪平和,眼藏静谧。

TOP

7楼正解

这样理解就可以了,虽然可能还是不太严谨,但我一直是这么过来的。
call的作用好多啊。调用、解析变量。
关于调用,call/?中说的已经很清楚了,可以对一个外部批处理进行调用的同时给它传递参数,也可以当前的另外一个标签进行调用,同样可以传递参数。示例:
  1. @echo off
  2. call :lp1 我是参数
  3. goto lp2
  4. :lp1
  5. echo %1
  6. goto :eof
  7. :lp2
  8. echo [%1] —— %%1在我这里不管用了。
  9. pause>nul&exit/b
复制代码
详细请参照这篇帖子: goto for call三种句式  http://bbs.bathome.net/viewthread.php?tid=1267
关于call解释变量,如下,测试两段代码。
一、
  1. @echo off
  2. :: %windir%
  3. :: Purification
  4. :: %computername%
  5. :: %username%
  6. :: %random% %random%
  7. :: %time%
  8. for /f "delims=" %%a in (%~fs0) do echo %%a
  9. pause
复制代码
二、
  1. @echo off
  2. :: %windir%
  3. :: Purification
  4. :: %computername%
  5. :: %username%
  6. :: %random% %random%
  7. :: %time%
  8. for /f "delims=" %%a in (%~fs0) do call echo %%a
  9. pause
复制代码

请先注意两段代码的区别。。第二个只不过比第一个多了一个call,运行,分别看下两段代码的输出结果。希望你能从中总结出什么道道。

[ 本帖最后由 pusofalse 于 2008-8-12 09:55 编辑 ]
心绪平和,眼藏静谧。

TOP

返回列表