BAT中setlocal EnableDelayedExpansion导致mysqldump失败

编写BAT文件时,发现setlocal EnableDelayedExpansion语法会导致mysqldump失败,原因不知道。去除那个setlocal语句后,mysqldump运行通过。

我在Windows服务器中有多个MySQL数据库,期望能做到自动备份,查了下资料,决定通过Windows执行计划调用BAT文件的方式实现。然后在写BAT文件时,马上就遇到了一个莫名其妙的问题:

@echo off
setlocal EnableDelayedExpansion
   
set d=%date:~0,4%%date:~5,2%%date:~8,2%
set bin=C:\Program Files\xxxxxxxxxx\bin\
set dbnames=db1,db2,db3,db4,db5
set folder=xxxxxxxxxxx

for %%a in (!dbnames!) do (
	"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "%%a" > "%folder%%%a_backup_!d!.sql"
)

@echo on

其中的mysqldump.exe语句行,会提示错误:

mysqldump.exe: Got error: 1045: "Access denied for user 'root'@'localhost' (using password: YES)" when trying to connect

但是把那行语句在cmd窗口中执行,却能通过。多方查找资料,没有能找任何跟这个问题相关的。

然后怀疑,是否是批处理里面的语句在for循环里,会被带入一个特殊的执行空间,跟mysqldump冲突了。于是修改批处理文件:

@echo off
setlocal EnableDelayedExpansion
   
set d=%date:~0,4%%date:~5,2%%date:~8,2%
set bin=C:\Program Files\xxxxxxxxxx\bin\
set dbnames=db1,db2,db3,db4,db5
set folder=xxxxxxxxxxx

"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "db1" > "%folder%db1_backup_!d!.sql"
"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "db2" > "%folder%db2_backup_!d!.sql"
"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "db3" > "%folder%db3_backup_!d!.sql"
"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "db4" > "%folder%db4_backup_!d!.sql"
"!bin!mysqldump.exe" --opt --single-transaction=1 --user=root --password=xxxxxxxxxxxxx --host=127.0.0.1 --protocol=tcp --port=3306 --default-character-set=utf8mb4 --routines --events "db5" > "%folder%db5_backup_!d!.sql"

@echo on

去掉了for,测试,问题依旧。

进一步简化,把!variable!语法全部换成%variable%语法,情况依旧;

把setlocal EnableDelayedExpansion语句行去掉,马上正常了。

原因分析:

我好多年没写BAT了,这个!variable!还从来没用过,百度查询得知:这是加上setlocal EnableDelayedExpansion语句后可用的语法;传统的%variable%更像是C语言里的宏定义,使用时立即替换成内容;!variable!更像编程语言里的变量,使用时看到的还是变量名。比如,BAT文件:

@echo off
setlocal EnableDelayedExpansion
set a=1
echo %a%
echo !a!
set /a b=!a!+1
echo %b%
@echo on

执行结果:

D:\>setlocal EnableDelayedExpansion
D:\>set a=1
D:\>echo 1
1
D:\>echo !a!
1
D:\>set /a b=!a!+1
D:\>echo 2
2

对比BAT文件和执行结果,发现%variable%语法被立即替换成了数值,!variable!语法则保留了原状直到执行,百度得知这叫“变量延迟扩展”,很高大上的概念。

然而,不知道什么原因,这个setlocal EnableDelayedExpansion竟然会影响到mysqldump的执行。

虽然问题解决了,但是遗憾没有找到根本原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值