批处理文件变量名有哪些限制,为什么?
我注意到我无法回显名为:)
的变量。
h:uprof>set :)=123
h:uprof>set :)
:)=123
h:uprof>echo %:)%
%:)%
显然,从批处理文件中输出:)
而不是%:)%
。问题显然不在于set
命令,因为变量及其值出现在set
的输出中。
奇怪的是,当分隔开-:
或)
-和反转的-):
-时,它们都会在用作变量名时输出给定的值。
唯一不能出现在用户定义的批处理环境变量名中的字符是=
。SET语句将在=
第一次出现时终止变量名,之后的所有内容都将是该值的一部分。
分配一个包含:
的变量名很简单,但除非在特定情况下,否则通常不能扩展该值。
启用扩展时(默认行为)
冒号是搜索/替换和子字符串扩展语法的一部分,它会干扰名称中包含冒号的变量的扩展。
有一个例外-如果:
作为名称中的最后一个字符出现,则变量可以很好地展开,但不能对值执行搜索和替换或子字符串展开操作。
当扩展被禁用时
搜索/替换和子字符串扩展不可用,因此没有什么可以阻止包含冒号的变量的扩展正常工作。
@echo off
setlocal enableExtensions
set "test:=[value of test:]"
set "test:more=[value of test:more]"
set "test"
echo(
echo With extensions enabled
echo -------------------------
echo %%test:%% = %test:%
echo %%test::test=replace%% = %test::test=replace%
echo %%test::~0,4%% = %test::~0,4%
echo %%test:more%% = %test:more%
setlocal disableExtensions
echo(
echo With extensions disabled
echo -------------------------
echo %%test:%% = %test:%
echo %%test:more%% = %test:more%
--输出--
test:=[value of test:]
test:more=[value of test:more]
With extensions enabled
-------------------------
%test:% = [value of test:]
%test::test=replace% = :test=replace
%test::~0,4% = :~0,4
%test:more% = more
With extensions disabled
-------------------------
%test:% = [value of test:]
%test:more% = [value of test:more]
请参阅https://stackoverflow.com/a/7970912/1012053以获得变量展开的确切工作方式的完整描述。
:
是用于变量扩展的字符串操作专用字符。示例:
%var:~0,1%
因此,如果变量名中:
后面有任何内容,它将尝试执行字符串操作,但失败。这允许:
冒号字符本身或在没有任何字符尾随时使用。
关于扩展变量名的规则:变量名不得包含后面跟有任何字符的:
,否则,变量扩展将失败。
参见set /?
set :)=123
set a)=123
set :a=123
set :=123
set )=123
echo %:)%
echo %a)%
echo %:a%
echo %:%
echo %)%
输出:
%:)%
123
%:a%
123
123
没有什么其他需要注意的。
如果您有一个名称以数字开头的变量,例如set "1var=foo"
,这会使批处理脚本解析器认为它处理的是参数%1
而不是变量%1var%
,即使没有传递参数,它仍然会扩展为空字符串,从而产生var%
。同样,如果用~
启动变量,解析器将期望一个以数字结尾的参数,如%~dp0
。但是,如果您不使用数字(set "~dp=bar"
)终止它,则无法使用%~dp%
访问它,因为这将导致错误:
The following usage of the path operator in batch-parameter substitution is invalid: %~dp%
仍然可以通过延迟扩展(!1var!
、!~dp!
)访问这些变量,但为了保持清楚,最好避免变量名首先以数字或波浪号开头。