概述
编写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 Filesxxxxxxxxxxbin
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 Filesxxxxxxxxxxbin
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的执行。
虽然问题解决了,但是遗憾没有找到根本原因。
最后
以上就是潇洒冷风为你收集整理的BAT中setlocal EnableDelayedExpansion导致mysqldump失败的全部内容,希望文章能够帮你解决BAT中setlocal EnableDelayedExpansion导致mysqldump失败所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复