回4f:
你所提供的2篇帖子都是非常不错的。“预处理和管道”中关于管道机制的探索确有独到之
处,但也存在不足,比如“pause|pause”为什么提示“过程试图写入的管道不存在。”,
而“set/p=t|pause”却正常,这里提及一点,pause的标准输出是 “请按任意键继续. . .
加上一个回车”,而set/p=t的标准输出为t,那么请测试“<nul pause|pause”,是不是正
常了,管道的问题就提到这里。因为我准备写一篇关于管道机制的帖子,所以关于管道机制
的其他问题在以后的帖子中再说吧。
“批处理脚本高级编程技巧——变量嵌套”中也没有讲到for是如何实现变量延迟扩展的,
你在2f中也只是简单比喻了下,一些朋友可能还是不知道原理。那么,下面就再说说for。
首先提及一点,for命令没有单独的命令处理模块,它和预处理共用一个命令分析处理模
块。在预处理过后,控制权交给for,当for进行一些格式匹配解释后,它会在调用一个新
的命令解释器将('command')中的命令提交该解释器解释执行,然后将执行结果传递给for
继续for命令的执行,下面以几个实例演示一下。
@echo off
for /f "delims=" %%i in ('echo.%%cmdcmdline%%') do (echo.%%i)
pause
从上面这段代码中可以看出for新调用的命令解释器为“C:\WINDOWS\system32\cmd.exe /c echo.%cmdcmdline%”
既然调用了新的命令解释器,那么预处理自然必不可少,从而就达到了延迟扩展的目的。
@echo off
for /f %%i in ('dir /b /ad %%windir%%^|find /v " "') do (echo.%%i)
pause
上面这段代码是一段很经典的过滤代码,目的是打印windows目录下的所有目录名但不打印含空格的目录名,试想
一下,如果('command')中的命令不再调用新的解释器解释而是直接执行,那么命令将会变成这个样子:
dir /b /ad %windir%|find /v " "
出现错误提示:无效的命令行开关 - "v"。
上面所说的 “set/p=t|pause” 只是为一个演示,其实我们还可以构造一个空传递,“<nul set/p=|pause”
同时也更新了顶楼的代码,使之更有趣一些
补充一下管道的原理: 管道1|管道2|管道3
以管道符为分割符,首先启动最后面一个命令(管道3),然后是倒数第二个(管道2),依此类推,然后
后一个命令会暂停以接收前一个命令的输出,如果命令输出为空则直接退出。
即:管道2接收管道1,管道3接收管道2,
最后,感谢2f的加分与肯定