I am trying to execute a windows batch command inside my python script using os.system(). My command looks like
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
.This works perfectly. However now my requirement is that instead of hardcoding the directory path, i want to pass it as a variable "REPO_PATH" and use the string format capability of python to pass this path in my command . Therefore my command should be
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 ''')`
To my surprise this command does not work. I have included my python script file too. What am I missing here?? Any help. My Python script file is shown below along with the outputs I get as comments next to the commands.
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."
This isn't a safe way to pass filenames to a shell at all. Ignoring that, though, the immediate problem is that you're putting .format(REPO_PATH)
inside the shell code, whereas it needs to be executed by the Python interpreter, not by cmd.exe
.
Compare:
# 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))
...you'll see that the former has .format(REPO_PATH)
inside the script text being passed to the shell, whereas the latter actually replaces the instances before invoking the shell.