非常感谢3742668版主的耐心解答, 变量加密中的环境变量代码转换我已经解决了, 谢谢你!
版主讲的字符变量化的方法可以把特殊字符显示出来, 我也对特殊字符的处理及批处理变量的处理机制有一点点自己的看法.
批处理以DOS程序为基础, 变量的定义使用非常方便, 并且批处理对变量的处理机制也很特殊. 它的变量值都可以当作命令成分执行, 我想这种机制除了批处理其他程序设计或脚本语言中都不会有. 举个例子:
@echo off
set "a=>"
echo dos i love you%a%dos.txt
pause
上面的代码证实, 把管道命令">"赋给a值, echo dos i love you%a%dos.txt在这一句代码中出现变量%a%, 当执行到这个语句时实际dos命令为(echo dos i love you>dos.txt), 这里他并不是会回显这个重定向符号, 而是当作命令把dos i love you重定向至dos.txt中. 系统自动在执行echo语句前从内存中找到变量a的值, 和释放到内存的整个echo语句一起当作命令执行了
这就是批处理的变量处理机制, 当执行语句前把语句中的变量先用变量值替换, 再执行, 这种处理机制有利也有弊, 它提高了批处理脚本的灵活性. 同时也会造成很多麻烦, 就像这个问题, 还有复合语句中变量的更新. 微软显然考虑到了这点, 它可以延迟环境变量扩充. 在执行语句前不先替换变量的值, 而是在语句执行后再根据变量取出相应的值, 把变量值当作数据处理.
要显示特殊字符, 我们就需要延缓环境变量扩充, 把这些字符不作为命令部分执行. 而是当做语句中的数据来处理.
@echo off
setlocal enabledelayedexpansion
set "a=>"
echo dos i love you!a!dos.txt
pause
上面的代码完整的显示echo dos i love you>dos.txt, 而没有重定向至dos.txt. 就是延缓变量扩充的结果, 它在echo命令执行到!a!时才把重定向符号从内存取出来显示, 并不是在命令执行前用变量值替换变量的位置.
@echo off
setlocal enabledelayedexpansion
set "a=&%!^|()|><+-"/*""
echo !a!
pause
3742668版主一楼的代码显示特殊字符也是利用延迟环境变量扩充, 不知道我这种说法是不是对的.
如果不用环境变量延迟扩充, 我们还可以利用控制字符的优先级来解决, 我们用引号来做个试验.
@echo off
set "a=&%!^|()|><+-"/*""
echo "%a%"
pause
或者
@echo off
set "a=&%!^|()|><+-"/*""
set /p "ii=%a%"<nul
pause
上面的代码说明引号可以将这些特殊字符当作需要加工的数据来处理, 而不是语句中的执行部分. 虽然没有开启延缓环境变量扩充, 但是这些特殊字符依然可以正常显示.
我对批处理也没有更深的理解, 不知如何解释. 目前我只好把他和C语言中的括号运算符来做比较. 引号的优先级高于这些一般的控制字符, 比如上面的管道命令符. 用引号括起来后系统把他们当作一般的字符处理了. 当语句执行到引号开始时, 系统认为引号内的部分是语句需要处理的数据, echo "%a%"这里=&%!^|()|><+-"/*"都会正常显示出来. 引号优化于&><等命令, 在echo命令执行时引号先于管道命令把特殊字符当做echo语句需要处理的数据执行.
我对这种机制也是似懂非懂, 还请3742668版主和高手们有更加准确说明.
Last edited by pengfei on 2006-12-4 at 03:54 AM ]