I understand that in a Windows batch file, %*
expands to all the command-line arguments, and that shift
shifts the numbered command-line arguments %1
, %2
, etc. but that it does not change the content of %*
.
What do I do if I want a version of %*
that does reflect the effect of shift
? I understand I could just say %1 %2 %3 %4 %5 %6 %7 %8 %9
after shifting but it seems stupid and potentially dangerous that that limits me to a fixed number of arguments.
Although this is not a python-specific question, it may help to understand that the reason I want this behaviour is that I've had to write a batch file SelectPython.bat
that pre-configures certain environment variables, in order to navigate the babel of different Python distros I have (you have to set %PYTHONHOME%
, %PYTHONPATH%
and %PATH%
in certain ways before you can call the Python binary and have confidence that you'll get the right distro). My current script works fine for setting these variables, but I would like to be able to call it and Python in one line - e.g.:
SelectPython C:\Python35 pythonw.exe myscript.py arg1 arg2 arg3 ...
Ideally I want my batch file to use shift
to "eat" the first argument, process it accordingly and set up the environment, and then just automatically chain-execute the string formed by rest of the arguments. The principle is analogous to the way env
wraps commands in posix systems:
env FOO=1 echo $FOO # wrap the `echo` command to be executed in the context of specified environment settings
So far I have this - the last line is where the problem is:
@echo off
set "LOC=%CD%
if not "%~1" == "" set "LOC=%~1
if exist "%LOC%\python.exe" goto :Success
echo "python.exe not found in %LOC%"
goto :eof
:Success
:: Canonicalize the resulting path:
pushd %LOC%
set "LOC=%CD%
popd
:: Let Python know where its own files are:
set "PYTHONHOME=%LOC%
set "PYTHONPATH=%LOC%;%LOC%\Lib\site-packages
:: Put Python's location at the beginning of the system path if it's not there already:
echo "%PATH%" | findstr /i /b /c:"%PYTHONHOME%" > nul || set "PATH=%PYTHONHOME%;%PYTHONHOME%\Scripts;%PATH%
:: Now execute the rest:
shift
if "%~1" == "" goto :eof
%1 %2 %3 %4 %5 %6 %7 %8 %9
:: This is unsatsifactory - what if there are more than 9 arguments?
UPDATE: Thanks to Stephan my working solution now has the following altered end-section:
:: Now execute the rest of the arguments, if any:
shift
if @%1 == @ goto :eof
set command=
:BuildCommand
if @%1 == @ goto :CommandFinished
set "command=%command% %1"
shift
goto :BuildCommand
:CommandFinished
%command%
build your own "%*" (I named it %params%
):
set "params="
:build
if @%1==@ goto :cont
shift
set "params=%params% %1"
goto :build
:cont
echo params are %params%
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With