首页 > 解决方案 > 由于空格和引号破坏了它,因此无法从另一个批处理文件中操作已解析的字符串

问题描述

我有一个批处理文件正在调用另一个批处理文件。批处理文件 1 正在将 5 个参数解析为批处理文件 2

当我将参数从批处理文件 1 解析到批处理文件 2 时,它会正确解析,但是当我分配这些解析的参数以在批处理文件 2 中使用它们时,它会中断。

批处理文件1:

ECHO
SET sql=SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";
SET pref=W
SET num=0
SET day=Friday
SET config=SampleSuperStore.txt
CALL Z:\XXX\RunTableauRefreshAutomatic.bat %sql% %pref% %num% %day% %config%

批处理文件2:

CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=%~1
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py %sql% %pref% %num% %day% %config%
PAUSE

批处理文件 2 的响应:

Z:\XXX>CALL C:\XXX\anaconda3\Scripts\activate.bat

(基础)Z:\XXX>SET sql=SELECT

(base) Z:\XXX>SET pref=MAX("Date")

(基础)Z:\XXX>SET num=FROM

(base) Z:\XXX>SET day=SQ_TEST."Sample - Superstore Ran"

(基础)Z:\XXX>SET config=W

(base) Z:\XXX>C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py SELECT MAX("Date") FROM DL_SQ_TEST."Sample - Superstore Ran" W

(base) Z:\XXX>PAUSE 按任意键继续。. .

更新:当我删除 sql 中的双引号时,它按预期工作,但我需要它们。另外我尝试使用 ^ 但批处理文件 2 仍然以不同的方式破坏它

标签: batch-file

解决方案


您可能会遇到更多问题,而不仅仅是空格!

将参数传递给 CALLed 脚本时,像&, |,>和等有毒字符是另一个问题。<如果所需的值是&"&",则不可能将该值作为文字字符串传递而不转义为 unquoted^&"&"或quoted "&"^&""。但是转义动态字符串是困难的/完全不切实际的。有时一个值必须通过多个调用,每个调用都需要自己的一轮转义。

通过插入符号时情况更糟 - 不可能通过^"^"。您可以将 unquoted 加倍^,但"^"由于 CALL 命令将quoted 加倍,所以引用是一个问题^,并且您绝对无法阻止它。例如CALL ECHO ^^"^"产量^"^^"

对于任何从事任何高级脚本编写的人来说,首先要学习的技巧之一就是通过引用而不是作为文字来传递值。调用脚本将值存储在变量中,并将变量的名称传递给 CALLed 脚本。CALLed 脚本然后使用延迟扩展来访问该值。所有讨厌的批处理问题都非常简单地解决了:-)

修改批处理文件1:

ECHO
SET sql=SELECT MAX("Date") FROM SQ_TEST."Sample - Superstore Ran";
SET pref=W
SET num=0
SET day=Friday
SET config=SampleSuperStore.txt
CALL Z:\XXX\RunTableauRefreshAutomatic.bat sql %pref% %num% %day% %config%

修改批处理文件2:

setlocal enableDelayedExpansion
CALL C:\XXX\anaconda3\Scripts\activate.bat 
SET sql=!%~1!
SET pref=%~2
SET num=%~3
SET day=%~4
SET config=%~5

:: I doubt this next line works properly.
C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py !sql! %pref% %num% %day% %config%

:: You probably need to change your python script to read the sql value from an environment
:: variable so you can then pass the value by reference just as we did with batch.
::
:: C:\XXX\anaconda3\python.exe Z:\XXX\pMainAutomaticDB.py sql %pref% %num% %day% %config%
::
:: Otherwise you will need to escape your quote literals - I believe python uses `\"`

PAUSE

另外需要注意的一件事 -!如果在启用延迟扩展的情况下访问,包含的字符串文字将被损坏。因此,除了上面列出的所有“问题”案例之外,如果值可能包含!.

请注意,您的 python 脚本还存在包含"文字的参数的潜在问题。我在修改后的第 2 批的评论中讨论了这一点。


推荐阅读