我正在尝试使用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)
放在了外壳程序代码中,而它需要由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 ''')
to
# 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))
...您会看到前者在传递给外壳程序的脚本文本中包含.format(REPO_PATH)
,而后者实际上是在调用外壳程序之前替换了实例。