字符串格式在用于批处理的 for-if-do 命令中不起作用

String formatting not working inside for-if-do command for batch processing

我正在尝试使用 os.system() 在我的 python 脚本中执行 windows 批处理命令。我的命令看起来像

os.system('''for %i in ("D:\u\demo4\v2\repository\..\p3\*.aar") do if exist "D:\u\demo4\v2\repository\com\aws\sdk\%~ni\%~nxi" copy "%~i" "D:\u\demo4\v2\repository\com\aws\sdk\%~ni\%~ni.aar" /Y ''')
# it works fine...when path "D:\u\demo4\v2\repository" is hard coded

。这很完美。但是现在我的要求是,我不想对目录路径进行硬编码,而是想将其作为变量 "REPO_PATH" 传递,并使用 python 的字符串格式功能在我的命令中传递此路径。因此我的命令应该是

os.system('''for %i in ("{}\..\p3\*.aar".format(REPO_PATH)) do if exist "{}\com\aws\sdk\%~ni\%~nxi".format(REPO_PATH) 
 copy "%~i" "{}\com\aws\sdk\%~ni\%~ni.aar".format(REPO_PATH) /Y ''')`

令我惊讶的是这个命令不起作用。我也包含了我的 python 脚本文件。我在这里错过了什么?任何帮助。下面显示了我的 Python 脚本文件以及我在命令旁边作为注释获得的输出。

import os,sys
REPO_PATH="D:\u\demo4\v2\repository"
print(REPO_PATH)


os.system('''for %i in ("D:\u\demo4\v2\repository\..\p3\*.aar") do if exist "D:\u\demo4\v2\repository\com\aws\sdk\%~ni\%~nxi" copy "%~i" "D:\u\demo4\v2\repository\com\aws\sdk\%~ni\%~ni.aar" /Y ''')
# it works fine...when path "D:\u\demo4\v2\repository" is hard coded


os.system('''for %i in ("{}\..\p3\*.aar".format(REPO_PATH)) do if exist "{}\com\aws\sdk\%~ni\%~nxi".format(REPO_PATH) copy "%~i" "{}\com\aws\sdk\%~ni\%~ni.aar".format(REPO_PATH) /Y ''')
#it gives error saying  ""{}\..\p3\*.aar".format was unexpected at this time."

这根本不是将文件名传递给 shell 的安全方法。但是,忽略这一点,直接的问题是您将 .format(REPO_PATH) 放在 shell 代码中,而它需要由 Python 解释器执行,而不是 cmd.exe .

比较:

# your original code, with print() instead of os.system(), to show the bug
REPO_PATH="D:\u\demo4\v2\repository"
print('''for %i in ("{}\..\p3\*.aar".format(REPO_PATH)) do if exist "{}\com\aws\sdk\%~ni\%~nxi".format(REPO_PATH) copy "%~i" "{}\com\aws\sdk\%~ni\%~ni.aar".format(REPO_PATH) /Y ''')

# only one format(), on the entire string, to *fix* the bug
REPO_PATH="D:\u\demo4\v2\repository"
print('''for %i in ("{0}\..\p3\*.aar") do if exist "{0}\com\aws\sdk\%~ni\%~nxi" copy "%~i" "{0}\com\aws\sdk\%~ni\%~ni.aar" /Y '''.format(REPO_PATH))

...你会看到前者在传递给 shell 的脚本文本中有 .format(REPO_PATH),而后者实际上在调用 shell 之前替换了实例.